summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commite1b2c9deb5943faae2b29be6a5c006f75bb73f06 (patch)
treefc79e45367c0a8fc71185e9afc33f7503a58653c /src
downloadqtxmlpatterns-e1b2c9deb5943faae2b29be6a5c006f75bb73f06.tar.gz
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src')
-rw-r--r--src/src.pro2
-rw-r--r--src/xmlpatterns/.gitignore1
-rw-r--r--src/xmlpatterns/Doxyfile1196
-rw-r--r--src/xmlpatterns/Mainpage.dox96
-rw-r--r--src/xmlpatterns/acceltree/acceltree.pri10
-rw-r--r--src/xmlpatterns/acceltree/qacceliterators.cpp181
-rw-r--r--src/xmlpatterns/acceltree/qacceliterators_p.h413
-rw-r--r--src/xmlpatterns/acceltree/qacceltree.cpp749
-rw-r--r--src/xmlpatterns/acceltree/qacceltree_p.h404
-rw-r--r--src/xmlpatterns/acceltree/qacceltreebuilder.cpp440
-rw-r--r--src/xmlpatterns/acceltree/qacceltreebuilder_p.h204
-rw-r--r--src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp441
-rw-r--r--src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h210
-rw-r--r--src/xmlpatterns/acceltree/qcompressedwhitespace.cpp197
-rw-r--r--src/xmlpatterns/acceltree/qcompressedwhitespace_p.h186
-rw-r--r--src/xmlpatterns/api/api.pri57
-rw-r--r--src/xmlpatterns/api/qabstractmessagehandler.cpp149
-rw-r--r--src/xmlpatterns/api/qabstractmessagehandler.h81
-rw-r--r--src/xmlpatterns/api/qabstracturiresolver.cpp111
-rw-r--r--src/xmlpatterns/api/qabstracturiresolver.h74
-rw-r--r--src/xmlpatterns/api/qabstractxmlforwarditerator.cpp269
-rw-r--r--src/xmlpatterns/api/qabstractxmlforwarditerator_p.h341
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel.cpp1683
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel.h429
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel_p.h81
-rw-r--r--src/xmlpatterns/api/qabstractxmlpullprovider.cpp177
-rw-r--r--src/xmlpatterns/api/qabstractxmlpullprovider_p.h113
-rw-r--r--src/xmlpatterns/api/qabstractxmlreceiver.cpp475
-rw-r--r--src/xmlpatterns/api/qabstractxmlreceiver.h107
-rw-r--r--src/xmlpatterns/api/qabstractxmlreceiver_p.h71
-rw-r--r--src/xmlpatterns/api/qcoloringmessagehandler.cpp198
-rw-r--r--src/xmlpatterns/api/qcoloringmessagehandler_p.h98
-rw-r--r--src/xmlpatterns/api/qcoloroutput.cpp377
-rw-r--r--src/xmlpatterns/api/qcoloroutput_p.h133
-rw-r--r--src/xmlpatterns/api/qdeviceresourceloader_p.h88
-rw-r--r--src/xmlpatterns/api/qiodevicedelegate.cpp166
-rw-r--r--src/xmlpatterns/api/qiodevicedelegate_p.h108
-rw-r--r--src/xmlpatterns/api/qnetworkaccessdelegator.cpp80
-rw-r--r--src/xmlpatterns/api/qnetworkaccessdelegator_p.h106
-rw-r--r--src/xmlpatterns/api/qpullbridge.cpp232
-rw-r--r--src/xmlpatterns/api/qpullbridge_p.h103
-rw-r--r--src/xmlpatterns/api/qreferencecountedvalue_p.h106
-rw-r--r--src/xmlpatterns/api/qresourcedelegator.cpp103
-rw-r--r--src/xmlpatterns/api/qresourcedelegator_p.h119
-rw-r--r--src/xmlpatterns/api/qsimplexmlnodemodel.cpp184
-rw-r--r--src/xmlpatterns/api/qsimplexmlnodemodel.h77
-rw-r--r--src/xmlpatterns/api/qsourcelocation.cpp240
-rw-r--r--src/xmlpatterns/api/qsourcelocation.h101
-rw-r--r--src/xmlpatterns/api/quriloader.cpp84
-rw-r--r--src/xmlpatterns/api/quriloader_p.h86
-rw-r--r--src/xmlpatterns/api/qvariableloader.cpp264
-rw-r--r--src/xmlpatterns/api/qvariableloader_p.h118
-rw-r--r--src/xmlpatterns/api/qxmlformatter.cpp338
-rw-r--r--src/xmlpatterns/api/qxmlformatter.h94
-rw-r--r--src/xmlpatterns/api/qxmlname.cpp511
-rw-r--r--src/xmlpatterns/api/qxmlname.h142
-rw-r--r--src/xmlpatterns/api/qxmlnamepool.cpp113
-rw-r--r--src/xmlpatterns/api/qxmlnamepool.h95
-rw-r--r--src/xmlpatterns/api/qxmlpatternistcli_p.h74
-rw-r--r--src/xmlpatterns/api/qxmlquery.cpp1209
-rw-r--r--src/xmlpatterns/api/qxmlquery.h155
-rw-r--r--src/xmlpatterns/api/qxmlquery_p.h328
-rw-r--r--src/xmlpatterns/api/qxmlresultitems.cpp152
-rw-r--r--src/xmlpatterns/api/qxmlresultitems.h77
-rw-r--r--src/xmlpatterns/api/qxmlresultitems_p.h87
-rw-r--r--src/xmlpatterns/api/qxmlschema.cpp304
-rw-r--r--src/xmlpatterns/api/qxmlschema.h97
-rw-r--r--src/xmlpatterns/api/qxmlschema_p.cpp203
-rw-r--r--src/xmlpatterns/api/qxmlschema_p.h109
-rw-r--r--src/xmlpatterns/api/qxmlschemavalidator.cpp349
-rw-r--r--src/xmlpatterns/api/qxmlschemavalidator.h97
-rw-r--r--src/xmlpatterns/api/qxmlschemavalidator_p.h131
-rw-r--r--src/xmlpatterns/api/qxmlserializer.cpp653
-rw-r--r--src/xmlpatterns/api/qxmlserializer.h158
-rw-r--r--src/xmlpatterns/api/qxmlserializer_p.h130
-rw-r--r--src/xmlpatterns/common.pri18
-rw-r--r--src/xmlpatterns/data/data.pri82
-rw-r--r--src/xmlpatterns/data/qabstractdatetime.cpp400
-rw-r--r--src/xmlpatterns/data/qabstractdatetime_p.h261
-rw-r--r--src/xmlpatterns/data/qabstractduration.cpp235
-rw-r--r--src/xmlpatterns/data/qabstractduration_p.h192
-rw-r--r--src/xmlpatterns/data/qabstractfloat.cpp321
-rw-r--r--src/xmlpatterns/data/qabstractfloat_p.h174
-rw-r--r--src/xmlpatterns/data/qabstractfloatcasters.cpp74
-rw-r--r--src/xmlpatterns/data/qabstractfloatcasters_p.h175
-rw-r--r--src/xmlpatterns/data/qabstractfloatmathematician.cpp97
-rw-r--r--src/xmlpatterns/data/qabstractfloatmathematician_p.h104
-rw-r--r--src/xmlpatterns/data/qanyuri.cpp104
-rw-r--r--src/xmlpatterns/data/qanyuri_p.h212
-rw-r--r--src/xmlpatterns/data/qatomiccaster.cpp56
-rw-r--r--src/xmlpatterns/data/qatomiccaster_p.h94
-rw-r--r--src/xmlpatterns/data/qatomiccasters.cpp336
-rw-r--r--src/xmlpatterns/data/qatomiccasters_p.h705
-rw-r--r--src/xmlpatterns/data/qatomiccomparator.cpp118
-rw-r--r--src/xmlpatterns/data/qatomiccomparator_p.h223
-rw-r--r--src/xmlpatterns/data/qatomiccomparators.cpp386
-rw-r--r--src/xmlpatterns/data/qatomiccomparators_p.h298
-rw-r--r--src/xmlpatterns/data/qatomicmathematician.cpp73
-rw-r--r--src/xmlpatterns/data/qatomicmathematician_p.h136
-rw-r--r--src/xmlpatterns/data/qatomicmathematicians.cpp352
-rw-r--r--src/xmlpatterns/data/qatomicmathematicians_p.h249
-rw-r--r--src/xmlpatterns/data/qatomicstring.cpp74
-rw-r--r--src/xmlpatterns/data/qatomicstring_p.h123
-rw-r--r--src/xmlpatterns/data/qatomicvalue.cpp238
-rw-r--r--src/xmlpatterns/data/qbase64binary.cpp216
-rw-r--r--src/xmlpatterns/data/qbase64binary_p.h118
-rw-r--r--src/xmlpatterns/data/qboolean.cpp137
-rw-r--r--src/xmlpatterns/data/qboolean_p.h126
-rw-r--r--src/xmlpatterns/data/qcommonvalues.cpp123
-rw-r--r--src/xmlpatterns/data/qcommonvalues_p.h228
-rw-r--r--src/xmlpatterns/data/qcomparisonfactory.cpp154
-rw-r--r--src/xmlpatterns/data/qcomparisonfactory_p.h121
-rw-r--r--src/xmlpatterns/data/qdate.cpp115
-rw-r--r--src/xmlpatterns/data/qdate_p.h95
-rw-r--r--src/xmlpatterns/data/qdaytimeduration.cpp242
-rw-r--r--src/xmlpatterns/data/qdaytimeduration_p.h154
-rw-r--r--src/xmlpatterns/data/qdecimal.cpp234
-rw-r--r--src/xmlpatterns/data/qdecimal_p.h156
-rw-r--r--src/xmlpatterns/data/qderivedinteger_p.h624
-rw-r--r--src/xmlpatterns/data/qderivedstring_p.h341
-rw-r--r--src/xmlpatterns/data/qduration.cpp244
-rw-r--r--src/xmlpatterns/data/qduration_p.h136
-rw-r--r--src/xmlpatterns/data/qgday.cpp96
-rw-r--r--src/xmlpatterns/data/qgday_p.h94
-rw-r--r--src/xmlpatterns/data/qgmonth.cpp95
-rw-r--r--src/xmlpatterns/data/qgmonth_p.h94
-rw-r--r--src/xmlpatterns/data/qgmonthday.cpp98
-rw-r--r--src/xmlpatterns/data/qgmonthday_p.h95
-rw-r--r--src/xmlpatterns/data/qgyear.cpp101
-rw-r--r--src/xmlpatterns/data/qgyear_p.h94
-rw-r--r--src/xmlpatterns/data/qgyearmonth.cpp103
-rw-r--r--src/xmlpatterns/data/qgyearmonth_p.h94
-rw-r--r--src/xmlpatterns/data/qhexbinary.cpp151
-rw-r--r--src/xmlpatterns/data/qhexbinary_p.h109
-rw-r--r--src/xmlpatterns/data/qinteger.cpp164
-rw-r--r--src/xmlpatterns/data/qinteger_p.h141
-rw-r--r--src/xmlpatterns/data/qitem.cpp58
-rw-r--r--src/xmlpatterns/data/qitem_p.h546
-rw-r--r--src/xmlpatterns/data/qnodebuilder.cpp48
-rw-r--r--src/xmlpatterns/data/qnodebuilder_p.h111
-rw-r--r--src/xmlpatterns/data/qnodemodel.cpp52
-rw-r--r--src/xmlpatterns/data/qqnamevalue.cpp75
-rw-r--r--src/xmlpatterns/data/qqnamevalue_p.h113
-rw-r--r--src/xmlpatterns/data/qresourceloader.cpp134
-rw-r--r--src/xmlpatterns/data/qresourceloader_p.h320
-rw-r--r--src/xmlpatterns/data/qschemadatetime.cpp117
-rw-r--r--src/xmlpatterns/data/qschemadatetime_p.h101
-rw-r--r--src/xmlpatterns/data/qschemanumeric.cpp91
-rw-r--r--src/xmlpatterns/data/qschemanumeric_p.h235
-rw-r--r--src/xmlpatterns/data/qschematime.cpp121
-rw-r--r--src/xmlpatterns/data/qschematime_p.h98
-rw-r--r--src/xmlpatterns/data/qsequencereceiver.cpp126
-rw-r--r--src/xmlpatterns/data/qsequencereceiver_p.h192
-rw-r--r--src/xmlpatterns/data/qsorttuple.cpp89
-rw-r--r--src/xmlpatterns/data/qsorttuple_p.h148
-rw-r--r--src/xmlpatterns/data/quntypedatomic.cpp64
-rw-r--r--src/xmlpatterns/data/quntypedatomic_p.h97
-rw-r--r--src/xmlpatterns/data/qvalidationerror.cpp90
-rw-r--r--src/xmlpatterns/data/qvalidationerror_p.h123
-rw-r--r--src/xmlpatterns/data/qvaluefactory.cpp106
-rw-r--r--src/xmlpatterns/data/qvaluefactory_p.h98
-rw-r--r--src/xmlpatterns/data/qyearmonthduration.cpp186
-rw-r--r--src/xmlpatterns/data/qyearmonthduration_p.h151
-rw-r--r--src/xmlpatterns/documentationGroups.dox150
-rwxr-xr-xsrc/xmlpatterns/environment/createReportContext.sh53
-rw-r--r--src/xmlpatterns/environment/createReportContext.xsl559
-rw-r--r--src/xmlpatterns/environment/environment.pri32
-rw-r--r--src/xmlpatterns/environment/qcurrentitemcontext.cpp62
-rw-r--r--src/xmlpatterns/environment/qcurrentitemcontext_p.h93
-rw-r--r--src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp212
-rw-r--r--src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h130
-rw-r--r--src/xmlpatterns/environment/qdelegatingstaticcontext.cpp261
-rw-r--r--src/xmlpatterns/environment/qdelegatingstaticcontext_p.h147
-rw-r--r--src/xmlpatterns/environment/qdynamiccontext.cpp68
-rw-r--r--src/xmlpatterns/environment/qdynamiccontext_p.h231
-rw-r--r--src/xmlpatterns/environment/qfocus.cpp107
-rw-r--r--src/xmlpatterns/environment/qfocus_p.h103
-rw-r--r--src/xmlpatterns/environment/qgenericdynamiccontext.cpp205
-rw-r--r--src/xmlpatterns/environment/qgenericdynamiccontext_p.h155
-rw-r--r--src/xmlpatterns/environment/qgenericstaticcontext.cpp338
-rw-r--r--src/xmlpatterns/environment/qgenericstaticcontext_p.h199
-rw-r--r--src/xmlpatterns/environment/qreceiverdynamiccontext.cpp61
-rw-r--r--src/xmlpatterns/environment/qreceiverdynamiccontext_p.h89
-rw-r--r--src/xmlpatterns/environment/qreportcontext.cpp479
-rw-r--r--src/xmlpatterns/environment/qreportcontext_p.h2464
-rw-r--r--src/xmlpatterns/environment/qstackcontextbase.cpp153
-rw-r--r--src/xmlpatterns/environment/qstackcontextbase_p.h136
-rw-r--r--src/xmlpatterns/environment/qstaticbaseuricontext.cpp62
-rw-r--r--src/xmlpatterns/environment/qstaticbaseuricontext_p.h91
-rw-r--r--src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp57
-rw-r--r--src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h84
-rw-r--r--src/xmlpatterns/environment/qstaticcontext.cpp61
-rw-r--r--src/xmlpatterns/environment/qstaticcontext_p.h299
-rw-r--r--src/xmlpatterns/environment/qstaticcurrentcontext.cpp60
-rw-r--r--src/xmlpatterns/environment/qstaticcurrentcontext_p.h90
-rw-r--r--src/xmlpatterns/environment/qstaticfocuscontext.cpp59
-rw-r--r--src/xmlpatterns/environment/qstaticfocuscontext_p.h91
-rw-r--r--src/xmlpatterns/environment/qstaticnamespacecontext.cpp60
-rw-r--r--src/xmlpatterns/environment/qstaticnamespacecontext_p.h89
-rw-r--r--src/xmlpatterns/expr/expr.pri173
-rw-r--r--src/xmlpatterns/expr/qandexpression.cpp97
-rw-r--r--src/xmlpatterns/expr/qandexpression_p.h98
-rw-r--r--src/xmlpatterns/expr/qapplytemplate.cpp210
-rw-r--r--src/xmlpatterns/expr/qapplytemplate_p.h144
-rw-r--r--src/xmlpatterns/expr/qargumentreference.cpp86
-rw-r--r--src/xmlpatterns/expr/qargumentreference_p.h94
-rw-r--r--src/xmlpatterns/expr/qarithmeticexpression.cpp363
-rw-r--r--src/xmlpatterns/expr/qarithmeticexpression_p.h133
-rw-r--r--src/xmlpatterns/expr/qattributeconstructor.cpp127
-rw-r--r--src/xmlpatterns/expr/qattributeconstructor_p.h108
-rw-r--r--src/xmlpatterns/expr/qattributenamevalidator.cpp109
-rw-r--r--src/xmlpatterns/expr/qattributenamevalidator_p.h99
-rw-r--r--src/xmlpatterns/expr/qaxisstep.cpp247
-rw-r--r--src/xmlpatterns/expr/qaxisstep_p.h168
-rw-r--r--src/xmlpatterns/expr/qcachecells_p.h157
-rw-r--r--src/xmlpatterns/expr/qcallsite.cpp68
-rw-r--r--src/xmlpatterns/expr/qcallsite_p.h111
-rw-r--r--src/xmlpatterns/expr/qcalltargetdescription.cpp107
-rw-r--r--src/xmlpatterns/expr/qcalltargetdescription_p.h120
-rw-r--r--src/xmlpatterns/expr/qcalltemplate.cpp153
-rw-r--r--src/xmlpatterns/expr/qcalltemplate_p.h117
-rw-r--r--src/xmlpatterns/expr/qcastableas.cpp157
-rw-r--r--src/xmlpatterns/expr/qcastableas_p.h111
-rw-r--r--src/xmlpatterns/expr/qcastas.cpp204
-rw-r--r--src/xmlpatterns/expr/qcastas_p.h148
-rw-r--r--src/xmlpatterns/expr/qcastingplatform.cpp221
-rw-r--r--src/xmlpatterns/expr/qcastingplatform_p.h206
-rw-r--r--src/xmlpatterns/expr/qcollationchecker.cpp79
-rw-r--r--src/xmlpatterns/expr/qcollationchecker_p.h99
-rw-r--r--src/xmlpatterns/expr/qcombinenodes.cpp172
-rw-r--r--src/xmlpatterns/expr/qcombinenodes_p.h116
-rw-r--r--src/xmlpatterns/expr/qcommentconstructor.cpp124
-rw-r--r--src/xmlpatterns/expr/qcommentconstructor_p.h100
-rw-r--r--src/xmlpatterns/expr/qcomparisonplatform.cpp199
-rw-r--r--src/xmlpatterns/expr/qcomparisonplatform_p.h208
-rw-r--r--src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp136
-rw-r--r--src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h102
-rw-r--r--src/xmlpatterns/expr/qcontextitem.cpp114
-rw-r--r--src/xmlpatterns/expr/qcontextitem_p.h128
-rw-r--r--src/xmlpatterns/expr/qcopyof.cpp134
-rw-r--r--src/xmlpatterns/expr/qcopyof_p.h121
-rw-r--r--src/xmlpatterns/expr/qcurrentitemstore.cpp139
-rw-r--r--src/xmlpatterns/expr/qcurrentitemstore_p.h104
-rw-r--r--src/xmlpatterns/expr/qdocumentconstructor.cpp116
-rw-r--r--src/xmlpatterns/expr/qdocumentconstructor_p.h103
-rw-r--r--src/xmlpatterns/expr/qdocumentcontentvalidator.cpp148
-rw-r--r--src/xmlpatterns/expr/qdocumentcontentvalidator_p.h117
-rw-r--r--src/xmlpatterns/expr/qdynamiccontextstore.cpp96
-rw-r--r--src/xmlpatterns/expr/qdynamiccontextstore_p.h97
-rw-r--r--src/xmlpatterns/expr/qelementconstructor.cpp160
-rw-r--r--src/xmlpatterns/expr/qelementconstructor_p.h107
-rw-r--r--src/xmlpatterns/expr/qemptycontainer.cpp69
-rw-r--r--src/xmlpatterns/expr/qemptycontainer_p.h101
-rw-r--r--src/xmlpatterns/expr/qemptysequence.cpp112
-rw-r--r--src/xmlpatterns/expr/qemptysequence_p.h136
-rw-r--r--src/xmlpatterns/expr/qevaluationcache.cpp274
-rw-r--r--src/xmlpatterns/expr/qevaluationcache_p.h146
-rw-r--r--src/xmlpatterns/expr/qexpression.cpp414
-rw-r--r--src/xmlpatterns/expr/qexpression_p.h909
-rw-r--r--src/xmlpatterns/expr/qexpressiondispatch_p.h241
-rw-r--r--src/xmlpatterns/expr/qexpressionfactory.cpp473
-rw-r--r--src/xmlpatterns/expr/qexpressionfactory_p.h187
-rw-r--r--src/xmlpatterns/expr/qexpressionsequence.cpp206
-rw-r--r--src/xmlpatterns/expr/qexpressionsequence_p.h127
-rw-r--r--src/xmlpatterns/expr/qexpressionvariablereference.cpp93
-rw-r--r--src/xmlpatterns/expr/qexpressionvariablereference_p.h114
-rw-r--r--src/xmlpatterns/expr/qexternalvariableloader.cpp94
-rw-r--r--src/xmlpatterns/expr/qexternalvariableloader_p.h139
-rw-r--r--src/xmlpatterns/expr/qexternalvariablereference.cpp88
-rw-r--r--src/xmlpatterns/expr/qexternalvariablereference_p.h103
-rw-r--r--src/xmlpatterns/expr/qfirstitempredicate.cpp97
-rw-r--r--src/xmlpatterns/expr/qfirstitempredicate_p.h114
-rw-r--r--src/xmlpatterns/expr/qforclause.cpp200
-rw-r--r--src/xmlpatterns/expr/qforclause_p.h122
-rw-r--r--src/xmlpatterns/expr/qgeneralcomparison.cpp297
-rw-r--r--src/xmlpatterns/expr/qgeneralcomparison_p.h136
-rw-r--r--src/xmlpatterns/expr/qgenericpredicate.cpp218
-rw-r--r--src/xmlpatterns/expr/qgenericpredicate_p.h148
-rw-r--r--src/xmlpatterns/expr/qifthenclause.cpp152
-rw-r--r--src/xmlpatterns/expr/qifthenclause_p.h101
-rw-r--r--src/xmlpatterns/expr/qinstanceof.cpp129
-rw-r--r--src/xmlpatterns/expr/qinstanceof_p.h101
-rw-r--r--src/xmlpatterns/expr/qletclause.cpp142
-rw-r--r--src/xmlpatterns/expr/qletclause_p.h109
-rw-r--r--src/xmlpatterns/expr/qliteral.cpp114
-rw-r--r--src/xmlpatterns/expr/qliteral_p.h148
-rw-r--r--src/xmlpatterns/expr/qliteralsequence.cpp92
-rw-r--r--src/xmlpatterns/expr/qliteralsequence_p.h104
-rw-r--r--src/xmlpatterns/expr/qnamespaceconstructor.cpp87
-rw-r--r--src/xmlpatterns/expr/qnamespaceconstructor_p.h109
-rw-r--r--src/xmlpatterns/expr/qncnameconstructor.cpp96
-rw-r--r--src/xmlpatterns/expr/qncnameconstructor_p.h154
-rw-r--r--src/xmlpatterns/expr/qnodecomparison.cpp184
-rw-r--r--src/xmlpatterns/expr/qnodecomparison_p.h127
-rw-r--r--src/xmlpatterns/expr/qnodesort.cpp142
-rw-r--r--src/xmlpatterns/expr/qnodesort_p.h98
-rw-r--r--src/xmlpatterns/expr/qoperandsiterator_p.h193
-rw-r--r--src/xmlpatterns/expr/qoptimizationpasses.cpp182
-rw-r--r--src/xmlpatterns/expr/qoptimizationpasses_p.h143
-rw-r--r--src/xmlpatterns/expr/qoptimizerblocks.cpp179
-rw-r--r--src/xmlpatterns/expr/qoptimizerblocks_p.h226
-rw-r--r--src/xmlpatterns/expr/qoptimizerframework.cpp71
-rw-r--r--src/xmlpatterns/expr/qoptimizerframework_p.h294
-rw-r--r--src/xmlpatterns/expr/qorderby.cpp261
-rw-r--r--src/xmlpatterns/expr/qorderby_p.h183
-rw-r--r--src/xmlpatterns/expr/qorexpression.cpp83
-rw-r--r--src/xmlpatterns/expr/qorexpression_p.h88
-rw-r--r--src/xmlpatterns/expr/qpaircontainer.cpp85
-rw-r--r--src/xmlpatterns/expr/qpaircontainer_p.h89
-rw-r--r--src/xmlpatterns/expr/qparentnodeaxis.cpp77
-rw-r--r--src/xmlpatterns/expr/qparentnodeaxis_p.h103
-rw-r--r--src/xmlpatterns/expr/qpath.cpp271
-rw-r--r--src/xmlpatterns/expr/qpath_p.h176
-rw-r--r--src/xmlpatterns/expr/qpositionalvariablereference.cpp84
-rw-r--r--src/xmlpatterns/expr/qpositionalvariablereference_p.h100
-rw-r--r--src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp144
-rw-r--r--src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h109
-rw-r--r--src/xmlpatterns/expr/qqnameconstructor.cpp114
-rw-r--r--src/xmlpatterns/expr/qqnameconstructor_p.h182
-rw-r--r--src/xmlpatterns/expr/qquantifiedexpression.cpp140
-rw-r--r--src/xmlpatterns/expr/qquantifiedexpression_p.h114
-rw-r--r--src/xmlpatterns/expr/qrangeexpression.cpp170
-rw-r--r--src/xmlpatterns/expr/qrangeexpression_p.h112
-rw-r--r--src/xmlpatterns/expr/qrangevariablereference.cpp92
-rw-r--r--src/xmlpatterns/expr/qrangevariablereference_p.h100
-rw-r--r--src/xmlpatterns/expr/qreturnorderby.cpp133
-rw-r--r--src/xmlpatterns/expr/qreturnorderby_p.h136
-rw-r--r--src/xmlpatterns/expr/qsimplecontentconstructor.cpp114
-rw-r--r--src/xmlpatterns/expr/qsimplecontentconstructor_p.h96
-rw-r--r--src/xmlpatterns/expr/qsinglecontainer.cpp76
-rw-r--r--src/xmlpatterns/expr/qsinglecontainer_p.h88
-rw-r--r--src/xmlpatterns/expr/qsourcelocationreflection.cpp65
-rw-r--r--src/xmlpatterns/expr/qsourcelocationreflection_p.h131
-rw-r--r--src/xmlpatterns/expr/qstaticbaseuristore.cpp82
-rw-r--r--src/xmlpatterns/expr/qstaticbaseuristore_p.h96
-rw-r--r--src/xmlpatterns/expr/qstaticcompatibilitystore.cpp79
-rw-r--r--src/xmlpatterns/expr/qstaticcompatibilitystore_p.h92
-rw-r--r--src/xmlpatterns/expr/qtemplate.cpp232
-rw-r--r--src/xmlpatterns/expr/qtemplate_p.h146
-rw-r--r--src/xmlpatterns/expr/qtemplateinvoker.cpp106
-rw-r--r--src/xmlpatterns/expr/qtemplateinvoker_p.h119
-rw-r--r--src/xmlpatterns/expr/qtemplatemode.cpp61
-rw-r--r--src/xmlpatterns/expr/qtemplatemode_p.h128
-rw-r--r--src/xmlpatterns/expr/qtemplateparameterreference.cpp91
-rw-r--r--src/xmlpatterns/expr/qtemplateparameterreference_p.h105
-rw-r--r--src/xmlpatterns/expr/qtemplatepattern_p.h161
-rw-r--r--src/xmlpatterns/expr/qtextnodeconstructor.cpp115
-rw-r--r--src/xmlpatterns/expr/qtextnodeconstructor_p.h97
-rw-r--r--src/xmlpatterns/expr/qtreatas.cpp92
-rw-r--r--src/xmlpatterns/expr/qtreatas_p.h122
-rw-r--r--src/xmlpatterns/expr/qtriplecontainer.cpp87
-rw-r--r--src/xmlpatterns/expr/qtriplecontainer_p.h92
-rw-r--r--src/xmlpatterns/expr/qtruthpredicate.cpp71
-rw-r--r--src/xmlpatterns/expr/qtruthpredicate_p.h112
-rw-r--r--src/xmlpatterns/expr/qunaryexpression.cpp79
-rw-r--r--src/xmlpatterns/expr/qunaryexpression_p.h114
-rw-r--r--src/xmlpatterns/expr/qunlimitedcontainer.cpp79
-rw-r--r--src/xmlpatterns/expr/qunlimitedcontainer_p.h149
-rw-r--r--src/xmlpatterns/expr/qunresolvedvariablereference.cpp91
-rw-r--r--src/xmlpatterns/expr/qunresolvedvariablereference_p.h111
-rw-r--r--src/xmlpatterns/expr/quserfunction.cpp62
-rw-r--r--src/xmlpatterns/expr/quserfunction_p.h135
-rw-r--r--src/xmlpatterns/expr/quserfunctioncallsite.cpp245
-rw-r--r--src/xmlpatterns/expr/quserfunctioncallsite_p.h182
-rw-r--r--src/xmlpatterns/expr/qvalidate.cpp77
-rw-r--r--src/xmlpatterns/expr/qvalidate_p.h106
-rw-r--r--src/xmlpatterns/expr/qvaluecomparison.cpp163
-rw-r--r--src/xmlpatterns/expr/qvaluecomparison_p.h138
-rw-r--r--src/xmlpatterns/expr/qvariabledeclaration.cpp63
-rw-r--r--src/xmlpatterns/expr/qvariabledeclaration_p.h203
-rw-r--r--src/xmlpatterns/expr/qvariablereference.cpp58
-rw-r--r--src/xmlpatterns/expr/qvariablereference_p.h121
-rw-r--r--src/xmlpatterns/expr/qwithparam_p.h123
-rw-r--r--src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp158
-rw-r--r--src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h89
-rw-r--r--src/xmlpatterns/functions/functions.pri96
-rw-r--r--src/xmlpatterns/functions/qabstractfunctionfactory.cpp103
-rw-r--r--src/xmlpatterns/functions/qabstractfunctionfactory_p.h157
-rw-r--r--src/xmlpatterns/functions/qaccessorfns.cpp159
-rw-r--r--src/xmlpatterns/functions/qaccessorfns_p.h138
-rw-r--r--src/xmlpatterns/functions/qaggregatefns.cpp316
-rw-r--r--src/xmlpatterns/functions/qaggregatefns_p.h156
-rw-r--r--src/xmlpatterns/functions/qaggregator.cpp69
-rw-r--r--src/xmlpatterns/functions/qaggregator_p.h94
-rw-r--r--src/xmlpatterns/functions/qassemblestringfns.cpp115
-rw-r--r--src/xmlpatterns/functions/qassemblestringfns_p.h103
-rw-r--r--src/xmlpatterns/functions/qbooleanfns.cpp71
-rw-r--r--src/xmlpatterns/functions/qbooleanfns_p.h119
-rw-r--r--src/xmlpatterns/functions/qcomparescaseaware.cpp71
-rw-r--r--src/xmlpatterns/functions/qcomparescaseaware_p.h98
-rw-r--r--src/xmlpatterns/functions/qcomparestringfns.cpp102
-rw-r--r--src/xmlpatterns/functions/qcomparestringfns_p.h102
-rw-r--r--src/xmlpatterns/functions/qcomparingaggregator.cpp212
-rw-r--r--src/xmlpatterns/functions/qcomparingaggregator_p.h146
-rw-r--r--src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp114
-rw-r--r--src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h95
-rw-r--r--src/xmlpatterns/functions/qcontextfns.cpp102
-rw-r--r--src/xmlpatterns/functions/qcontextfns_p.h195
-rw-r--r--src/xmlpatterns/functions/qcontextnodechecker.cpp63
-rw-r--r--src/xmlpatterns/functions/qcontextnodechecker_p.h85
-rw-r--r--src/xmlpatterns/functions/qcurrentfn.cpp75
-rw-r--r--src/xmlpatterns/functions/qcurrentfn_p.h89
-rw-r--r--src/xmlpatterns/functions/qdatetimefn.cpp96
-rw-r--r--src/xmlpatterns/functions/qdatetimefn_p.h82
-rw-r--r--src/xmlpatterns/functions/qdatetimefns.cpp145
-rw-r--r--src/xmlpatterns/functions/qdatetimefns_p.h305
-rw-r--r--src/xmlpatterns/functions/qdeepequalfn.cpp162
-rw-r--r--src/xmlpatterns/functions/qdeepequalfn_p.h94
-rw-r--r--src/xmlpatterns/functions/qdocumentfn.cpp115
-rw-r--r--src/xmlpatterns/functions/qdocumentfn_p.h124
-rw-r--r--src/xmlpatterns/functions/qelementavailablefn.cpp120
-rw-r--r--src/xmlpatterns/functions/qelementavailablefn_p.h87
-rw-r--r--src/xmlpatterns/functions/qerrorfn.cpp113
-rw-r--r--src/xmlpatterns/functions/qerrorfn_p.h91
-rw-r--r--src/xmlpatterns/functions/qfunctionargument.cpp66
-rw-r--r--src/xmlpatterns/functions/qfunctionargument_p.h98
-rw-r--r--src/xmlpatterns/functions/qfunctionavailablefn.cpp91
-rw-r--r--src/xmlpatterns/functions/qfunctionavailablefn_p.h92
-rw-r--r--src/xmlpatterns/functions/qfunctioncall.cpp160
-rw-r--r--src/xmlpatterns/functions/qfunctioncall_p.h102
-rw-r--r--src/xmlpatterns/functions/qfunctionfactory.cpp79
-rw-r--r--src/xmlpatterns/functions/qfunctionfactory_p.h168
-rw-r--r--src/xmlpatterns/functions/qfunctionfactorycollection.cpp138
-rw-r--r--src/xmlpatterns/functions/qfunctionfactorycollection_p.h118
-rw-r--r--src/xmlpatterns/functions/qfunctionsignature.cpp158
-rw-r--r--src/xmlpatterns/functions/qfunctionsignature_p.h213
-rw-r--r--src/xmlpatterns/functions/qgenerateidfn.cpp63
-rw-r--r--src/xmlpatterns/functions/qgenerateidfn_p.h83
-rw-r--r--src/xmlpatterns/functions/qnodefns.cpp209
-rw-r--r--src/xmlpatterns/functions/qnodefns_p.h176
-rw-r--r--src/xmlpatterns/functions/qnumericfns.cpp107
-rw-r--r--src/xmlpatterns/functions/qnumericfns_p.h140
-rw-r--r--src/xmlpatterns/functions/qpatternmatchingfns.cpp230
-rw-r--r--src/xmlpatterns/functions/qpatternmatchingfns_p.h139
-rw-r--r--src/xmlpatterns/functions/qpatternplatform.cpp301
-rw-r--r--src/xmlpatterns/functions/qpatternplatform_p.h195
-rw-r--r--src/xmlpatterns/functions/qqnamefns.cpp189
-rw-r--r--src/xmlpatterns/functions/qqnamefns_p.h162
-rw-r--r--src/xmlpatterns/functions/qresolveurifn.cpp87
-rw-r--r--src/xmlpatterns/functions/qresolveurifn_p.h82
-rw-r--r--src/xmlpatterns/functions/qsequencefns.cpp352
-rw-r--r--src/xmlpatterns/functions/qsequencefns_p.h344
-rw-r--r--src/xmlpatterns/functions/qsequencegeneratingfns.cpp291
-rw-r--r--src/xmlpatterns/functions/qsequencegeneratingfns_p.h167
-rw-r--r--src/xmlpatterns/functions/qstaticbaseuricontainer_p.h107
-rw-r--r--src/xmlpatterns/functions/qstaticnamespacescontainer.cpp57
-rw-r--r--src/xmlpatterns/functions/qstaticnamespacescontainer_p.h115
-rw-r--r--src/xmlpatterns/functions/qstringvaluefns.cpp373
-rw-r--r--src/xmlpatterns/functions/qstringvaluefns_p.h293
-rw-r--r--src/xmlpatterns/functions/qsubstringfns.cpp173
-rw-r--r--src/xmlpatterns/functions/qsubstringfns_p.h136
-rw-r--r--src/xmlpatterns/functions/qsystempropertyfn.cpp101
-rw-r--r--src/xmlpatterns/functions/qsystempropertyfn_p.h92
-rw-r--r--src/xmlpatterns/functions/qtimezonefns.cpp166
-rw-r--r--src/xmlpatterns/functions/qtimezonefns_p.h136
-rw-r--r--src/xmlpatterns/functions/qtracefn.cpp140
-rw-r--r--src/xmlpatterns/functions/qtracefn_p.h94
-rw-r--r--src/xmlpatterns/functions/qtypeavailablefn.cpp74
-rw-r--r--src/xmlpatterns/functions/qtypeavailablefn_p.h92
-rw-r--r--src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp56
-rw-r--r--src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h82
-rw-r--r--src/xmlpatterns/functions/qunparsedentityurifn.cpp56
-rw-r--r--src/xmlpatterns/functions/qunparsedentityurifn_p.h82
-rw-r--r--src/xmlpatterns/functions/qunparsedtextavailablefn.cpp85
-rw-r--r--src/xmlpatterns/functions/qunparsedtextavailablefn_p.h83
-rw-r--r--src/xmlpatterns/functions/qunparsedtextfn.cpp82
-rw-r--r--src/xmlpatterns/functions/qunparsedtextfn_p.h83
-rw-r--r--src/xmlpatterns/functions/qxpath10corefunctions.cpp300
-rw-r--r--src/xmlpatterns/functions/qxpath10corefunctions_p.h93
-rw-r--r--src/xmlpatterns/functions/qxpath20corefunctions.cpp748
-rw-r--r--src/xmlpatterns/functions/qxpath20corefunctions_p.h96
-rw-r--r--src/xmlpatterns/functions/qxslt20corefunctions.cpp175
-rw-r--r--src/xmlpatterns/functions/qxslt20corefunctions_p.h94
-rw-r--r--src/xmlpatterns/iterators/iterators.pri29
-rw-r--r--src/xmlpatterns/iterators/qcachingiterator.cpp130
-rw-r--r--src/xmlpatterns/iterators/qcachingiterator_p.h129
-rw-r--r--src/xmlpatterns/iterators/qdeduplicateiterator.cpp95
-rw-r--r--src/xmlpatterns/iterators/qdeduplicateiterator_p.h103
-rw-r--r--src/xmlpatterns/iterators/qdistinctiterator.cpp112
-rw-r--r--src/xmlpatterns/iterators/qdistinctiterator_p.h128
-rw-r--r--src/xmlpatterns/iterators/qemptyiterator_p.h146
-rw-r--r--src/xmlpatterns/iterators/qexceptiterator.cpp122
-rw-r--r--src/xmlpatterns/iterators/qexceptiterator_p.h101
-rw-r--r--src/xmlpatterns/iterators/qindexofiterator.cpp115
-rw-r--r--src/xmlpatterns/iterators/qindexofiterator_p.h129
-rw-r--r--src/xmlpatterns/iterators/qinsertioniterator.cpp128
-rw-r--r--src/xmlpatterns/iterators/qinsertioniterator_p.h120
-rw-r--r--src/xmlpatterns/iterators/qintersectiterator.cpp115
-rw-r--r--src/xmlpatterns/iterators/qintersectiterator_p.h107
-rw-r--r--src/xmlpatterns/iterators/qitemmappingiterator_p.h190
-rw-r--r--src/xmlpatterns/iterators/qrangeiterator.cpp126
-rw-r--r--src/xmlpatterns/iterators/qrangeiterator_p.h141
-rw-r--r--src/xmlpatterns/iterators/qremovaliterator.cpp109
-rw-r--r--src/xmlpatterns/iterators/qremovaliterator_p.h122
-rw-r--r--src/xmlpatterns/iterators/qsequencemappingiterator_p.h237
-rw-r--r--src/xmlpatterns/iterators/qsingletoniterator_p.h177
-rw-r--r--src/xmlpatterns/iterators/qsubsequenceiterator.cpp110
-rw-r--r--src/xmlpatterns/iterators/qsubsequenceiterator_p.h118
-rw-r--r--src/xmlpatterns/iterators/qtocodepointsiterator.cpp95
-rw-r--r--src/xmlpatterns/iterators/qtocodepointsiterator_p.h103
-rw-r--r--src/xmlpatterns/iterators/qunioniterator.cpp131
-rw-r--r--src/xmlpatterns/iterators/qunioniterator_p.h107
-rw-r--r--src/xmlpatterns/janitors/janitors.pri13
-rw-r--r--src/xmlpatterns/janitors/qargumentconverter.cpp104
-rw-r--r--src/xmlpatterns/janitors/qargumentconverter_p.h103
-rw-r--r--src/xmlpatterns/janitors/qatomizer.cpp125
-rw-r--r--src/xmlpatterns/janitors/qatomizer_p.h110
-rw-r--r--src/xmlpatterns/janitors/qcardinalityverifier.cpp224
-rw-r--r--src/xmlpatterns/janitors/qcardinalityverifier_p.h128
-rw-r--r--src/xmlpatterns/janitors/qebvextractor.cpp90
-rw-r--r--src/xmlpatterns/janitors/qebvextractor_p.h109
-rw-r--r--src/xmlpatterns/janitors/qitemverifier.cpp122
-rw-r--r--src/xmlpatterns/janitors/qitemverifier_p.h103
-rw-r--r--src/xmlpatterns/janitors/quntypedatomicconverter.cpp113
-rw-r--r--src/xmlpatterns/janitors/quntypedatomicconverter_p.h127
-rw-r--r--src/xmlpatterns/parser/.gitattributes4
-rw-r--r--src/xmlpatterns/parser/.gitignore1
-rw-r--r--src/xmlpatterns/parser/TokenLookup.gperf223
-rwxr-xr-xsrc/xmlpatterns/parser/createParser.sh55
-rwxr-xr-xsrc/xmlpatterns/parser/createTokenLookup.sh91
-rwxr-xr-xsrc/xmlpatterns/parser/createXSLTTokenLookup.sh44
-rw-r--r--src/xmlpatterns/parser/parser.pri19
-rw-r--r--src/xmlpatterns/parser/qmaintainingreader.cpp274
-rw-r--r--src/xmlpatterns/parser/qmaintainingreader_p.h234
-rw-r--r--src/xmlpatterns/parser/qparsercontext.cpp100
-rw-r--r--src/xmlpatterns/parser/qparsercontext_p.h433
-rw-r--r--src/xmlpatterns/parser/qquerytransformparser.cpp8035
-rw-r--r--src/xmlpatterns/parser/qquerytransformparser_p.h338
-rw-r--r--src/xmlpatterns/parser/qtokenizer_p.h216
-rw-r--r--src/xmlpatterns/parser/qtokenlookup.cpp444
-rw-r--r--src/xmlpatterns/parser/qtokenrevealer.cpp111
-rw-r--r--src/xmlpatterns/parser/qtokenrevealer_p.h97
-rw-r--r--src/xmlpatterns/parser/qtokensource.cpp53
-rw-r--r--src/xmlpatterns/parser/qtokensource_p.h169
-rw-r--r--src/xmlpatterns/parser/querytransformparser.ypp4680
-rw-r--r--src/xmlpatterns/parser/qxquerytokenizer.cpp2249
-rw-r--r--src/xmlpatterns/parser/qxquerytokenizer_p.h332
-rw-r--r--src/xmlpatterns/parser/qxslttokenizer.cpp2717
-rw-r--r--src/xmlpatterns/parser/qxslttokenizer_p.h481
-rw-r--r--src/xmlpatterns/parser/qxslttokenlookup.cpp3006
-rw-r--r--src/xmlpatterns/parser/qxslttokenlookup.xml167
-rw-r--r--src/xmlpatterns/parser/qxslttokenlookup_p.h213
-rw-r--r--src/xmlpatterns/parser/trolltechHeader.txt51
-rw-r--r--src/xmlpatterns/parser/winCEWorkaround.sed32
-rw-r--r--src/xmlpatterns/projection/projection.pri4
-rw-r--r--src/xmlpatterns/projection/qdocumentprojector.cpp214
-rw-r--r--src/xmlpatterns/projection/qdocumentprojector_p.h107
-rw-r--r--src/xmlpatterns/projection/qprojectedexpression_p.h165
-rw-r--r--src/xmlpatterns/qtokenautomaton/README66
-rw-r--r--src/xmlpatterns/qtokenautomaton/exampleFile.xml65
-rw-r--r--src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl298
-rw-r--r--src/xmlpatterns/qtokenautomaton/qtokenautomaton.xsd89
-rw-r--r--src/xmlpatterns/query.pri14
-rw-r--r--src/xmlpatterns/schema/.gitignore1
-rw-r--r--src/xmlpatterns/schema/builtinschemas.qrc5
-rw-r--r--src/xmlpatterns/schema/doc/All_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Alternative_diagram.dot11
-rw-r--r--src/xmlpatterns/schema/doc/Annotation_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Any_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Assert_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Choice_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot47
-rw-r--r--src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot47
-rw-r--r--src/xmlpatterns/schema/doc/ComplexContent_diagram.dot11
-rw-r--r--src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Field_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot52
-rw-r--r--src/xmlpatterns/schema/doc/GlobalElement_diagram.dot32
-rw-r--r--src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Import_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Include_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/KeyRef_diagram.dot12
-rw-r--r--src/xmlpatterns/schema/doc/Key_diagram.dot12
-rw-r--r--src/xmlpatterns/schema/doc/LengthFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/List_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/LocalAll_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/LocalChoice_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot52
-rw-r--r--src/xmlpatterns/schema/doc/LocalElement_diagram.dot32
-rw-r--r--src/xmlpatterns/schema/doc/LocalSequence_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot17
-rw-r--r--src/xmlpatterns/schema/doc/NamedGroup_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Notation_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Override_diagram.dot21
-rw-r--r--src/xmlpatterns/schema/doc/PatternFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Redefine_diagram.dot15
-rw-r--r--src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Schema_diagram.dot66
-rw-r--r--src/xmlpatterns/schema/doc/Selector_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Sequence_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot23
-rw-r--r--src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot87
-rw-r--r--src/xmlpatterns/schema/doc/SimpleContent_diagram.dot11
-rw-r--r--src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot62
-rw-r--r--src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Union_diagram.dot10
-rw-r--r--src/xmlpatterns/schema/doc/Unique_diagram.dot12
-rw-r--r--src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/legend.dot7
-rw-r--r--src/xmlpatterns/schema/qnamespacesupport.cpp160
-rw-r--r--src/xmlpatterns/schema/qnamespacesupport_p.h173
-rw-r--r--src/xmlpatterns/schema/qxsdalternative.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdalternative_p.h114
-rw-r--r--src/xmlpatterns/schema/qxsdannotated.cpp63
-rw-r--r--src/xmlpatterns/schema/qxsdannotated_p.h96
-rw-r--r--src/xmlpatterns/schema/qxsdannotation.cpp78
-rw-r--r--src/xmlpatterns/schema/qxsdannotation_p.h127
-rw-r--r--src/xmlpatterns/schema/qxsdapplicationinformation.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdapplicationinformation_p.h115
-rw-r--r--src/xmlpatterns/schema/qxsdassertion.cpp58
-rw-r--r--src/xmlpatterns/schema/qxsdassertion_p.h101
-rw-r--r--src/xmlpatterns/schema/qxsdattribute.cpp130
-rw-r--r--src/xmlpatterns/schema/qxsdattribute_p.h246
-rw-r--r--src/xmlpatterns/schema/qxsdattributegroup.cpp73
-rw-r--r--src/xmlpatterns/schema/qxsdattributegroup_p.h122
-rw-r--r--src/xmlpatterns/schema/qxsdattributereference.cpp88
-rw-r--r--src/xmlpatterns/schema/qxsdattributereference_p.h147
-rw-r--r--src/xmlpatterns/schema/qxsdattributeterm.cpp58
-rw-r--r--src/xmlpatterns/schema/qxsdattributeterm_p.h96
-rw-r--r--src/xmlpatterns/schema/qxsdattributeuse.cpp136
-rw-r--r--src/xmlpatterns/schema/qxsdattributeuse_p.h224
-rw-r--r--src/xmlpatterns/schema/qxsdcomplextype.cpp231
-rw-r--r--src/xmlpatterns/schema/qxsdcomplextype_p.h404
-rw-r--r--src/xmlpatterns/schema/qxsddocumentation.cpp86
-rw-r--r--src/xmlpatterns/schema/qxsddocumentation_p.h137
-rw-r--r--src/xmlpatterns/schema/qxsdelement.cpp244
-rw-r--r--src/xmlpatterns/schema/qxsdelement_p.h403
-rw-r--r--src/xmlpatterns/schema/qxsdfacet.cpp124
-rw-r--r--src/xmlpatterns/schema/qxsdfacet_p.h213
-rw-r--r--src/xmlpatterns/schema/qxsdidcache.cpp66
-rw-r--r--src/xmlpatterns/schema/qxsdidcache_p.h99
-rw-r--r--src/xmlpatterns/schema/qxsdidchelper.cpp137
-rw-r--r--src/xmlpatterns/schema/qxsdidchelper_p.h186
-rw-r--r--src/xmlpatterns/schema/qxsdidentityconstraint.cpp93
-rw-r--r--src/xmlpatterns/schema/qxsdidentityconstraint_p.h173
-rw-r--r--src/xmlpatterns/schema/qxsdinstancereader.cpp196
-rw-r--r--src/xmlpatterns/schema/qxsdinstancereader_p.h189
-rw-r--r--src/xmlpatterns/schema/qxsdmodelgroup.cpp78
-rw-r--r--src/xmlpatterns/schema/qxsdmodelgroup_p.h139
-rw-r--r--src/xmlpatterns/schema/qxsdnotation.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdnotation_p.h119
-rw-r--r--src/xmlpatterns/schema/qxsdparticle.cpp95
-rw-r--r--src/xmlpatterns/schema/qxsdparticle_p.h154
-rw-r--r--src/xmlpatterns/schema/qxsdparticlechecker.cpp570
-rw-r--r--src/xmlpatterns/schema/qxsdparticlechecker_p.h106
-rw-r--r--src/xmlpatterns/schema/qxsdreference.cpp83
-rw-r--r--src/xmlpatterns/schema/qxsdreference_p.h145
-rw-r--r--src/xmlpatterns/schema/qxsdschema.cpp272
-rw-r--r--src/xmlpatterns/schema/qxsdschema_p.h301
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker.cpp2061
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker_helper.cpp306
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker_p.h284
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker_setup.cpp327
-rw-r--r--src/xmlpatterns/schema/qxsdschemacontext.cpp528
-rw-r--r--src/xmlpatterns/schema/qxsdschemacontext_p.h187
-rw-r--r--src/xmlpatterns/schema/qxsdschemadebugger.cpp226
-rw-r--r--src/xmlpatterns/schema/qxsdschemadebugger_p.h127
-rw-r--r--src/xmlpatterns/schema/qxsdschemahelper.cpp821
-rw-r--r--src/xmlpatterns/schema/qxsdschemahelper_p.h217
-rw-r--r--src/xmlpatterns/schema/qxsdschemamerger.cpp157
-rw-r--r--src/xmlpatterns/schema/qxsdschemamerger_p.h99
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparser.cpp6119
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparser_p.h739
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparser_setup.cpp1110
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparsercontext.cpp603
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparsercontext_p.h231
-rw-r--r--src/xmlpatterns/schema/qxsdschemaresolver.cpp1743
-rw-r--r--src/xmlpatterns/schema/qxsdschemaresolver_p.h578
-rw-r--r--src/xmlpatterns/schema/qxsdschematoken.cpp2981
-rw-r--r--src/xmlpatterns/schema/qxsdschematoken_p.h209
-rw-r--r--src/xmlpatterns/schema/qxsdschematypesfactory.cpp126
-rw-r--r--src/xmlpatterns/schema/qxsdschematypesfactory_p.h109
-rw-r--r--src/xmlpatterns/schema/qxsdsimpletype.cpp148
-rw-r--r--src/xmlpatterns/schema/qxsdsimpletype_p.h219
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachine.cpp413
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachine_p.h308
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp260
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h141
-rw-r--r--src/xmlpatterns/schema/qxsdterm.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdterm_p.h114
-rw-r--r--src/xmlpatterns/schema/qxsdtypechecker.cpp1339
-rw-r--r--src/xmlpatterns/schema/qxsdtypechecker_p.h189
-rw-r--r--src/xmlpatterns/schema/qxsduserschematype.cpp75
-rw-r--r--src/xmlpatterns/schema/qxsduserschematype_p.h124
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp215
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h179
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp1276
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h296
-rw-r--r--src/xmlpatterns/schema/qxsdwildcard.cpp115
-rw-r--r--src/xmlpatterns/schema/qxsdwildcard_p.h199
-rw-r--r--src/xmlpatterns/schema/qxsdxpathexpression.cpp88
-rw-r--r--src/xmlpatterns/schema/qxsdxpathexpression_p.h143
-rw-r--r--src/xmlpatterns/schema/schema.pri93
-rw-r--r--src/xmlpatterns/schema/schemas/xml.xsd145
-rw-r--r--src/xmlpatterns/schema/schemas/xml.xsd-LICENSE40
-rw-r--r--src/xmlpatterns/schema/tokens.xml155
-rw-r--r--src/xmlpatterns/type/qabstractnodetest.cpp78
-rw-r--r--src/xmlpatterns/type/qabstractnodetest_p.h87
-rw-r--r--src/xmlpatterns/type/qanyitemtype.cpp90
-rw-r--r--src/xmlpatterns/type/qanyitemtype_p.h119
-rw-r--r--src/xmlpatterns/type/qanynodetype.cpp98
-rw-r--r--src/xmlpatterns/type/qanynodetype_p.h113
-rw-r--r--src/xmlpatterns/type/qanysimpletype.cpp93
-rw-r--r--src/xmlpatterns/type/qanysimpletype_p.h130
-rw-r--r--src/xmlpatterns/type/qanytype.cpp103
-rw-r--r--src/xmlpatterns/type/qanytype_p.h142
-rw-r--r--src/xmlpatterns/type/qatomiccasterlocator.cpp82
-rw-r--r--src/xmlpatterns/type/qatomiccasterlocator_p.h126
-rw-r--r--src/xmlpatterns/type/qatomiccasterlocators.cpp252
-rw-r--r--src/xmlpatterns/type/qatomiccasterlocators_p.h909
-rw-r--r--src/xmlpatterns/type/qatomiccomparatorlocator.cpp91
-rw-r--r--src/xmlpatterns/type/qatomiccomparatorlocator_p.h132
-rw-r--r--src/xmlpatterns/type/qatomiccomparatorlocators.cpp232
-rw-r--r--src/xmlpatterns/type/qatomiccomparatorlocators_p.h356
-rw-r--r--src/xmlpatterns/type/qatomicmathematicianlocator.cpp85
-rw-r--r--src/xmlpatterns/type/qatomicmathematicianlocator_p.h158
-rw-r--r--src/xmlpatterns/type/qatomicmathematicianlocators.cpp168
-rw-r--r--src/xmlpatterns/type/qatomicmathematicianlocators_p.h249
-rw-r--r--src/xmlpatterns/type/qatomictype.cpp118
-rw-r--r--src/xmlpatterns/type/qatomictype_p.h160
-rw-r--r--src/xmlpatterns/type/qatomictypedispatch_p.h277
-rw-r--r--src/xmlpatterns/type/qbasictypesfactory.cpp128
-rw-r--r--src/xmlpatterns/type/qbasictypesfactory_p.h121
-rw-r--r--src/xmlpatterns/type/qbuiltinatomictype.cpp94
-rw-r--r--src/xmlpatterns/type/qbuiltinatomictype_p.h130
-rw-r--r--src/xmlpatterns/type/qbuiltinatomictypes.cpp226
-rw-r--r--src/xmlpatterns/type/qbuiltinatomictypes_p.h789
-rw-r--r--src/xmlpatterns/type/qbuiltinnodetype.cpp165
-rw-r--r--src/xmlpatterns/type/qbuiltinnodetype_p.h110
-rw-r--r--src/xmlpatterns/type/qbuiltintypes.cpp161
-rw-r--r--src/xmlpatterns/type/qbuiltintypes_p.h174
-rw-r--r--src/xmlpatterns/type/qcardinality.cpp102
-rw-r--r--src/xmlpatterns/type/qcardinality_p.h544
-rw-r--r--src/xmlpatterns/type/qcommonsequencetypes.cpp132
-rw-r--r--src/xmlpatterns/type/qcommonsequencetypes_p.h414
-rw-r--r--src/xmlpatterns/type/qebvtype.cpp123
-rw-r--r--src/xmlpatterns/type/qebvtype_p.h135
-rw-r--r--src/xmlpatterns/type/qemptysequencetype.cpp101
-rw-r--r--src/xmlpatterns/type/qemptysequencetype_p.h124
-rw-r--r--src/xmlpatterns/type/qgenericsequencetype.cpp72
-rw-r--r--src/xmlpatterns/type/qgenericsequencetype_p.h115
-rw-r--r--src/xmlpatterns/type/qitemtype.cpp103
-rw-r--r--src/xmlpatterns/type/qitemtype_p.h286
-rw-r--r--src/xmlpatterns/type/qlocalnametest.cpp99
-rw-r--r--src/xmlpatterns/type/qlocalnametest_p.h102
-rw-r--r--src/xmlpatterns/type/qmultiitemtype.cpp140
-rw-r--r--src/xmlpatterns/type/qmultiitemtype_p.h146
-rw-r--r--src/xmlpatterns/type/qnamedschemacomponent.cpp71
-rw-r--r--src/xmlpatterns/type/qnamedschemacomponent_p.h127
-rw-r--r--src/xmlpatterns/type/qnamespacenametest.cpp95
-rw-r--r--src/xmlpatterns/type/qnamespacenametest_p.h101
-rw-r--r--src/xmlpatterns/type/qnonetype.cpp104
-rw-r--r--src/xmlpatterns/type/qnonetype_p.h155
-rw-r--r--src/xmlpatterns/type/qnumerictype.cpp142
-rw-r--r--src/xmlpatterns/type/qnumerictype_p.h174
-rw-r--r--src/xmlpatterns/type/qprimitives_p.h203
-rw-r--r--src/xmlpatterns/type/qqnametest.cpp99
-rw-r--r--src/xmlpatterns/type/qqnametest_p.h103
-rw-r--r--src/xmlpatterns/type/qschemacomponent.cpp56
-rw-r--r--src/xmlpatterns/type/qschemacomponent_p.h85
-rw-r--r--src/xmlpatterns/type/qschematype.cpp80
-rw-r--r--src/xmlpatterns/type/qschematype_p.h248
-rw-r--r--src/xmlpatterns/type/qschematypefactory.cpp56
-rw-r--r--src/xmlpatterns/type/qschematypefactory_p.h102
-rw-r--r--src/xmlpatterns/type/qsequencetype.cpp65
-rw-r--r--src/xmlpatterns/type/qsequencetype_p.h138
-rw-r--r--src/xmlpatterns/type/qtypechecker.cpp296
-rw-r--r--src/xmlpatterns/type/qtypechecker_p.h185
-rw-r--r--src/xmlpatterns/type/quntyped.cpp79
-rw-r--r--src/xmlpatterns/type/quntyped_p.h112
-rw-r--r--src/xmlpatterns/type/qxsltnodetest.cpp72
-rw-r--r--src/xmlpatterns/type/qxsltnodetest_p.h100
-rw-r--r--src/xmlpatterns/type/type.pri72
-rw-r--r--src/xmlpatterns/utils/qautoptr.cpp48
-rw-r--r--src/xmlpatterns/utils/qautoptr_p.h175
-rw-r--r--src/xmlpatterns/utils/qcommonnamespaces_p.h152
-rw-r--r--src/xmlpatterns/utils/qcppcastinghelper_p.h161
-rw-r--r--src/xmlpatterns/utils/qdebug_p.h107
-rw-r--r--src/xmlpatterns/utils/qdelegatingnamespaceresolver.cpp92
-rw-r--r--src/xmlpatterns/utils/qdelegatingnamespaceresolver_p.h96
-rw-r--r--src/xmlpatterns/utils/qgenericnamespaceresolver.cpp96
-rw-r--r--src/xmlpatterns/utils/qgenericnamespaceresolver_p.h113
-rw-r--r--src/xmlpatterns/utils/qnamepool.cpp418
-rw-r--r--src/xmlpatterns/utils/qnamepool_p.h556
-rw-r--r--src/xmlpatterns/utils/qnamespacebinding_p.h143
-rw-r--r--src/xmlpatterns/utils/qnamespaceresolver.cpp57
-rw-r--r--src/xmlpatterns/utils/qnamespaceresolver_p.h119
-rw-r--r--src/xmlpatterns/utils/qnodenamespaceresolver.cpp83
-rw-r--r--src/xmlpatterns/utils/qnodenamespaceresolver_p.h91
-rw-r--r--src/xmlpatterns/utils/qoutputvalidator.cpp162
-rw-r--r--src/xmlpatterns/utils/qoutputvalidator_p.h127
-rw-r--r--src/xmlpatterns/utils/qpatternistlocale.cpp91
-rw-r--r--src/xmlpatterns/utils/qpatternistlocale_p.h281
-rw-r--r--src/xmlpatterns/utils/qxpathhelper.cpp140
-rw-r--r--src/xmlpatterns/utils/qxpathhelper_p.h179
-rw-r--r--src/xmlpatterns/utils/utils.pri21
-rw-r--r--src/xmlpatterns/xmlpatterns.pro37
810 files changed, 160139 insertions, 0 deletions
diff --git a/src/src.pro b/src/src.pro
new file mode 100644
index 0000000..cd32a1b
--- /dev/null
+++ b/src/src.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += xmlpatterns
diff --git a/src/xmlpatterns/.gitignore b/src/xmlpatterns/.gitignore
new file mode 100644
index 0000000..eb12d93
--- /dev/null
+++ b/src/xmlpatterns/.gitignore
@@ -0,0 +1 @@
+internal-docs/
diff --git a/src/xmlpatterns/Doxyfile b/src/xmlpatterns/Doxyfile
new file mode 100644
index 0000000..83f7062
--- /dev/null
+++ b/src/xmlpatterns/Doxyfile
@@ -0,0 +1,1196 @@
+# Doxyfile 1.4.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = QtXmlPatterns
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = internal-docs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = yes
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is YES.
+
+SHOW_DIRECTORIES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+# Having it set to not, output a lot of status messages to stdout, we still
+# get the warning into the log file
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = internal-docs/doxygen.log
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = . ../../tests/auto/xmlpatternsxqts/ ../../tests/auto/xmlpatternsview
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+
+FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.dox *.gperf
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+# The Qt API uses qdoc and Doxygen doesn't like its tags, so exclude the q* files.
+EXCLUDE_PATTERNS = *.moc *.moc.cpp moc_*.cpp ui_*.h
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT =
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = Q_SLOTS="slots" \
+ Q_SIGNALS="signals"
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+CALLER_GRAPH = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS = schema/doc/
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/src/xmlpatterns/Mainpage.dox b/src/xmlpatterns/Mainpage.dox
new file mode 100644
index 0000000..641619c
--- /dev/null
+++ b/src/xmlpatterns/Mainpage.dox
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
+/**
+ * @mainpage QtXmlPatterns -- an implementation of XML technologies
+ *
+ * - @ref Patternist_info
+ * - @ref Patternist_writingDoxygen
+ *
+ * @section Patternist_info Overview
+ *
+ * This is the internal developer documentation for QtXmlPatterns. Please refer
+ * to Qt Assistant for usage documentation.
+ *
+ * The documentation that you are reading right now, can be generated by
+ * running <tt>doxygen</tt> in this directory without arguments. The generated
+ * documentation can subsequently be browsed from
+ * <tt>internal-docs/html/index.html</tt>.
+ *
+ * @subsection Patternist_writingDoxygen Doxygen Conventions
+ *
+ * Doxygen conventions, are as follows.
+ *
+ * - <tt>@@returns</tt> and <tt>@@param</tt> paragraphs are terminated with a period.
+ * - When XPath or XQuery expressions/queries appears in the Doxygen comments, wrap them
+ * in the @c tt HTML tag.
+ * - Classes and free standing functions should have an <tt>@@author</tt> tag, specifying who
+ * is the main author of it.
+ * - No code examples should appear directly in the Doxygen comments, they should be included with
+ * <tt>@@include</tt> or <tt>@@dontinclude</tt>.
+ * - The following terms are marked with <tt>@@c</tt> or the @c tt HTML tag:
+ * - @c NaN
+ * - @c true and @c false, when referred to as boolean values
+ * - All QNames and item types. For example, <tt>item\()</tt> and <tt>xs:string</tt>. Remember
+ * to use the @c tt HTML tag in these cases in order to include non-trivial characters
+ * such as paranteses
+ * - @c null
+ * - @c stderr, @c stdout, and @c stdin
+ *
+ *
+ * The current Doxygen comments does in some cases not adhere to this, but the
+ * idea is to harmonize in that direction over time.
+ *
+ * PatternistSDK, located in the test sources, is documented in the
+ * PatternistSDK Doxygen module.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
diff --git a/src/xmlpatterns/acceltree/acceltree.pri b/src/xmlpatterns/acceltree/acceltree.pri
new file mode 100644
index 0000000..284371a
--- /dev/null
+++ b/src/xmlpatterns/acceltree/acceltree.pri
@@ -0,0 +1,10 @@
+SOURCES += $$PWD/qacceltree.cpp \
+ $$PWD/qacceltreeresourceloader.cpp \
+ $$PWD/qacceliterators.cpp \
+ $$PWD/qcompressedwhitespace.cpp
+
+HEADERS += $$PWD/qacceltreebuilder_p.h \
+ $$PWD/qacceltree_p.h \
+ $$PWD/qacceltreeresourceloader_p.h \
+ $$PWD/qacceliterators_p.h \
+ $$PWD/qcompressedwhitespace_p.h
diff --git a/src/xmlpatterns/acceltree/qacceliterators.cpp b/src/xmlpatterns/acceltree/qacceliterators.cpp
new file mode 100644
index 0000000..20cd805
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceliterators.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDebug>
+
+#include "qacceliterators_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+xsInteger AccelIterator::position() const
+{
+ return m_position;
+}
+
+QXmlNodeModelIndex AccelIterator::current() const
+{
+ return m_current;
+}
+
+QXmlNodeModelIndex FollowingIterator::next()
+{
+ /* "the following axis contains all nodes that are descendants
+ * of the root of the tree in which the context node is found,
+ * are not descendants of the context node, and occur after
+ * the context node in document order." */
+
+ if(m_position == 0)
+ {
+ /* Skip the descendants. */
+ m_currentPre += m_document->size(m_preNumber) + 1;
+ }
+
+ if(m_currentPre > m_document->maximumPreNumber())
+ return closedExit();
+
+ while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute)
+ {
+ ++m_currentPre;
+ if(m_currentPre > m_document->maximumPreNumber())
+ return closedExit();
+ }
+
+ m_current = m_document->createIndex(m_currentPre);
+ ++m_position;
+ ++m_currentPre;
+ return m_current;
+}
+
+QXmlNodeModelIndex PrecedingIterator::next()
+{
+ if(m_currentPre == -1)
+ return closedExit();
+
+ /* We skip ancestors and attributes and take into account that they can be intermixed. If one
+ * skips them in two separate loops, one can end up with skipping all the attributes to then
+ * be positioned at an ancestor(which will be accepted because the ancestor loop was before the
+ * attributes loop). */
+ while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute ||
+ m_document->postNumber(m_currentPre) > m_postNumber)
+ {
+ --m_currentPre;
+ if(m_currentPre == -1)
+ return closedExit();
+ }
+
+ if(m_currentPre == -1)
+ {
+ m_currentPre = -1;
+ return closedExit();
+ }
+
+ /* Phew, m_currentPre is now 1) not an ancestor; and
+ * 2) not an attribute; and 3) preceds the context node. */
+
+ m_current = m_document->createIndex(m_currentPre);
+ ++m_position;
+ --m_currentPre;
+
+ return m_current;
+}
+
+QXmlNodeModelIndex::Iterator::Ptr PrecedingIterator::copy() const
+{
+ return QXmlNodeModelIndex::Iterator::Ptr(new PrecedingIterator(m_document, m_preNumber));
+}
+
+QXmlNodeModelIndex::Iterator::Ptr FollowingIterator::copy() const
+{
+ return QXmlNodeModelIndex::Iterator::Ptr(new FollowingIterator(m_document, m_preNumber));
+}
+
+QXmlNodeModelIndex ChildIterator::next()
+{
+ if(m_currentPre == -1)
+ return closedExit();
+
+ ++m_position;
+ m_current = m_document->createIndex(m_currentPre);
+
+ /* We get the count of the descendants, and increment m_currentPre. After
+ * this, m_currentPre is the node after the descendants. */
+ m_currentPre += m_document->size(m_currentPre);
+ ++m_currentPre;
+
+ if(m_currentPre > m_document->maximumPreNumber() || m_document->depth(m_currentPre) != m_depth)
+ m_currentPre = -1;
+
+ return m_current;
+}
+
+QXmlNodeModelIndex::Iterator::Ptr ChildIterator::copy() const
+{
+ return QXmlNodeModelIndex::Iterator::Ptr(new ChildIterator(m_document, m_preNumber));
+}
+
+QXmlNodeModelIndex AttributeIterator::next()
+{
+ if(m_currentPre == -1)
+ return closedExit();
+ else
+ {
+ m_current = m_document->createIndex(m_currentPre);
+ ++m_position;
+
+ ++m_currentPre;
+
+ if(m_currentPre > m_document->maximumPreNumber() ||
+ m_document->kind(m_currentPre) != QXmlNodeModelIndex::Attribute)
+ m_currentPre = -1;
+
+ return m_current;
+ }
+}
+
+QXmlNodeModelIndex::Iterator::Ptr AttributeIterator::copy() const
+{
+ return QXmlNodeModelIndex::Iterator::Ptr(new AttributeIterator(m_document, m_preNumber));
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/acceltree/qacceliterators_p.h b/src/xmlpatterns/acceltree/qacceliterators_p.h
new file mode 100644
index 0000000..e472fb2
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceliterators_p.h
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AccelIterators_H
+#define Patternist_AccelIterators_H
+
+#include "qacceltree_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Abstract base class for Iterators for the AccelTree, that
+ * contains common functions and members.
+ *
+ * @author Frans Englich<frans.englich@nokia.com>
+ */
+ class AccelIterator : public QXmlNodeModelIndex::Iterator
+ {
+ public:
+ virtual xsInteger position() const;
+ virtual QXmlNodeModelIndex current() const;
+
+ protected:
+ inline AccelIterator(const AccelTree *const doc,
+ const AccelTree::PreNumber pre,
+ const AccelTree::PreNumber currentPre) : m_document(doc)
+ , m_preNumber(pre)
+ , m_currentPre(currentPre)
+ , m_position(0)
+
+ {
+ Q_ASSERT(m_document);
+ Q_ASSERT(m_preNumber >= 0);
+ }
+
+ inline QXmlNodeModelIndex closedExit()
+ {
+ m_position = -1;
+ m_current.reset();
+ return QXmlNodeModelIndex();
+ }
+
+ /**
+ * We do not own it.
+ */
+ const AccelTree *const m_document;
+
+ /**
+ * The pre number of the node that should be navigated from.
+ */
+ const AccelTree::PreNumber m_preNumber;
+ AccelTree::PreNumber m_currentPre;
+ xsInteger m_position;
+ QXmlNodeModelIndex m_current;
+ };
+
+ /**
+ * @short Iterates along the @c ancestor or @c ancestor-or-self axis in an AccelTree.
+ *
+ * @author Frans Englich<frans.englich@nokia.com>
+ */
+ template<const bool IncludeSelf>
+ class AncestorIterator : public AccelIterator
+ {
+ public:
+ /**
+ * @p pre is the node from which iteration starts
+ * from. In the @c ancestor axis it is excluded,
+ * while in @c ancestor-or-self it is included. @p pre
+ * must have at least one ancestor.
+ */
+ inline AncestorIterator(const AccelTree *const doc,
+ const AccelTree::PreNumber pre) : AccelIterator(doc, pre, IncludeSelf ? pre : doc->basicData.at(pre).parent())
+ {
+ Q_ASSERT(IncludeSelf || m_document->hasParent(pre));
+ }
+
+ virtual QXmlNodeModelIndex next()
+ {
+ if(m_currentPre == -1)
+ return closedExit();
+ else
+ {
+ ++m_position;
+ m_current = m_document->createIndex(m_currentPre);
+ m_currentPre = m_document->basicData.at(m_currentPre).parent();
+
+ return m_current;
+ }
+ }
+
+ virtual QXmlNodeModelIndex::Iterator::Ptr copy() const
+ {
+ return QXmlNodeModelIndex::Iterator::Ptr(new AncestorIterator<IncludeSelf>(m_document, m_preNumber));
+ }
+ };
+
+ /**
+ * @short Iterates along the @c child axis in an AccelTree.
+ *
+ * @author Frans Englich<frans.englich@nokia.com>
+ */
+ class ChildIterator : public AccelIterator
+ {
+ public:
+ /**
+ * @p pre must have at least one child.
+ */
+ inline ChildIterator(const AccelTree *const doc,
+ const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + 1),
+ m_depth(m_document->depth(m_currentPre))
+ {
+ Q_ASSERT(m_document->hasChildren(pre));
+
+ /* Skip the attributes, that are children in the pre/post plane, of
+ * the node we're applying the child axis to. */
+ while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute)
+ {
+ ++m_currentPre;
+ /* We check the depth here because we would otherwise include
+ * following siblings. */
+ if(m_currentPre > m_document->maximumPreNumber() || m_document->depth(m_currentPre) != m_depth)
+ {
+ m_currentPre = -1;
+ break;
+ }
+ }
+ }
+
+ virtual QXmlNodeModelIndex next();
+ virtual QXmlNodeModelIndex::Iterator::Ptr copy() const;
+
+ private:
+ const AccelTree::Depth m_depth;
+ };
+
+ /**
+ * @short Iterates along the sibling axes in an AccelTree.
+ *
+ * @author Frans Englich<frans.englich@nokia.com>
+ */
+ template<const bool IsFollowing>
+ class SiblingIterator : public AccelIterator
+ {
+ public:
+ inline SiblingIterator(const AccelTree *const doc,
+ const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + (IsFollowing ? 0 : -1)),
+ m_depth(doc->depth(pre))
+ {
+ Q_ASSERT_X(IsFollowing || pre != 0, "",
+ "When being preceding-sibling, the context node cannot be the first node in the document.");
+ Q_ASSERT_X(!IsFollowing || pre != m_document->maximumPreNumber(), "",
+ "When being following-sibling, the context node cannot be the last node in the document.");
+ }
+
+ virtual QXmlNodeModelIndex next()
+ {
+ if(m_currentPre == -1)
+ return QXmlNodeModelIndex();
+
+ if(IsFollowing)
+ {
+ /* Skip the descendants, and jump to the next node. */
+ m_currentPre += m_document->size(m_currentPre) + 1;
+
+ if(m_currentPre > m_document->maximumPreNumber() || m_document->depth(m_currentPre) != m_depth)
+ return closedExit();
+ else
+ {
+ ++m_position;
+ m_current = m_document->createIndex(m_currentPre);
+ return m_current;
+ }
+ }
+ else
+ {
+ while(m_document->depth(m_currentPre) > m_depth)
+ --m_currentPre;
+
+ while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute)
+ --m_currentPre;
+
+ if(m_document->depth(m_currentPre) == m_depth &&
+ m_document->kind(m_currentPre) != QXmlNodeModelIndex::Attribute)
+ {
+ m_current = m_document->createIndex(m_currentPre);
+ ++m_position;
+ --m_currentPre;
+ return m_current;
+ }
+ else
+ {
+ m_currentPre = -1;
+ return closedExit();
+ }
+ }
+ }
+
+ virtual QXmlNodeModelIndex::Iterator::Ptr copy() const
+ {
+ return QXmlNodeModelIndex::Iterator::Ptr(new SiblingIterator<IsFollowing>(m_document, m_preNumber));
+ }
+
+ private:
+ const AccelTree::Depth m_depth;
+ };
+
+ /**
+ * @short Implements axis @c descendant and @c descendant-or-self for the
+ * AccelTree.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<const bool IncludeSelf>
+ class DescendantIterator : public AccelIterator
+ {
+ public:
+ /**
+ * @p pre must have at least one child.
+ */
+ inline DescendantIterator(const AccelTree *const doc,
+ const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + (IncludeSelf ? 0 : 1)),
+ m_postNumber(doc->postNumber(pre))
+ {
+ Q_ASSERT(IncludeSelf || m_document->hasChildren(pre));
+
+ /* Make sure that m_currentPre is the first node part of this axis.
+ * Since we're not including ourself, advance to the node after our
+ * attributes, if any. */
+ if(!IncludeSelf)
+ {
+ while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute)
+ {
+ ++m_currentPre;
+ /* We check the depth here because we would otherwise include
+ * following siblings. */
+ if(m_currentPre > m_document->maximumPreNumber() || m_document->postNumber(m_currentPre) > m_postNumber)
+ {
+ m_currentPre = -1;
+ break;
+ }
+ }
+ }
+ }
+
+ virtual QXmlNodeModelIndex next()
+ {
+ if(m_currentPre == -1)
+ return closedExit();
+
+ ++m_position;
+ m_current = m_document->createIndex(m_currentPre);
+
+ ++m_currentPre;
+
+ if(m_currentPre > m_document->maximumPreNumber())
+ {
+ m_currentPre = -1;
+ return m_current;
+ }
+
+ if(m_document->postNumber(m_currentPre) < m_postNumber)
+ {
+ while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute)
+ {
+ ++m_currentPre;
+ if(m_currentPre > m_document->maximumPreNumber())
+ {
+ m_currentPre = -1;
+ break;
+ }
+ }
+ }
+ else
+ m_currentPre = -1;
+
+ return m_current;
+ }
+
+ virtual QXmlNodeModelIndex::Iterator::Ptr copy() const
+ {
+ return QXmlNodeModelIndex::Iterator::Ptr(new DescendantIterator<IncludeSelf>(m_document, m_preNumber));
+ }
+
+ private:
+ const AccelTree::PreNumber m_postNumber;
+ };
+
+ /**
+ * @short Implements axis @c following for the AccelTree.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class FollowingIterator : public AccelIterator
+ {
+ public:
+ /**
+ * @ pre must have at least one child.
+ */
+ inline FollowingIterator(const AccelTree *const doc,
+ const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre)
+ {
+ }
+
+ virtual QXmlNodeModelIndex next();
+ virtual QXmlNodeModelIndex::Iterator::Ptr copy() const;
+ };
+
+ /**
+ * @short Implements axis @c preceding for the AccelTree.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class PrecedingIterator : public AccelIterator
+ {
+ public:
+ /**
+ * @ pre must have at least one child.
+ */
+ inline PrecedingIterator(const AccelTree *const doc,
+ const AccelTree::PreNumber pre) : AccelIterator(doc, pre,
+ pre - 1 /* currentPre */)
+ , m_postNumber(m_document->postNumber(m_preNumber))
+ {
+ }
+
+ virtual QXmlNodeModelIndex next();
+ virtual QXmlNodeModelIndex::Iterator::Ptr copy() const;
+
+ private:
+ const AccelTree::PreNumber m_postNumber;
+ };
+
+ /**
+ * @short Implements axis @c attribute for the AccelTree.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AttributeIterator : public AccelIterator
+ {
+ public:
+ /**
+ * @p pre must have at least one child.
+ */
+ inline AttributeIterator(const AccelTree *const doc, const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + 1)
+ {
+ Q_ASSERT(m_document->hasChildren(pre));
+ Q_ASSERT(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute);
+ }
+
+ virtual QXmlNodeModelIndex next();
+ virtual QXmlNodeModelIndex::Iterator::Ptr copy() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/acceltree/qacceltree.cpp b/src/xmlpatterns/acceltree/qacceltree.cpp
new file mode 100644
index 0000000..f2f383a
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltree.cpp
@@ -0,0 +1,749 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStack>
+
+#include "qabstractxmlreceiver.h"
+#include "qabstractxmlnodemodel_p.h"
+#include "qacceliterators_p.h"
+#include "qacceltree_p.h"
+#include "qatomicstring_p.h"
+#include "qcommonvalues_p.h"
+#include "qcompressedwhitespace_p.h"
+#include "qdebug_p.h"
+#include "quntypedatomic_p.h"
+#include "qxpathhelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist {
+
+ class AccelTreePrivate : public QAbstractXmlNodeModelPrivate
+ {
+ public:
+ AccelTreePrivate(AccelTree *accelTree)
+ : m_accelTree(accelTree)
+ {
+ }
+
+ virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const
+ {
+ return m_accelTree->sourceLocation(index);
+ }
+
+ private:
+ AccelTree *m_accelTree;
+ };
+}
+
+AccelTree::AccelTree(const QUrl &docURI, const QUrl &bURI)
+ : QAbstractXmlNodeModel(new AccelTreePrivate(this))
+ , m_documentURI(docURI)
+ , m_baseURI(bURI)
+{
+ /* Pre-allocate at least a little bit. */
+ // TODO. Do it according to what an average 4 KB doc contains.
+ basicData.reserve(100);
+ data.reserve(30);
+}
+
+void AccelTree::printStats(const NamePool::Ptr &np) const
+{
+ Q_ASSERT(np);
+#ifdef QT_NO_DEBUG
+ Q_UNUSED(np); /* Needed when compiling in release mode. */
+#else
+ const int len = basicData.count();
+
+ pDebug() << "AccelTree stats for" << (m_documentURI.isEmpty() ? QString::fromLatin1("<empty URI>") : m_documentURI.toString());
+ pDebug() << "Maximum pre number:" << maximumPreNumber();
+ pDebug() << "+---------------+-------+-------+---------------+-------+--------------+-------+";
+ pDebug() << "| Pre number | Depth | Size | Post Number | Kind | Name | Value |";
+ pDebug() << "+---------------+-------+-------+---------------+-------+--------------+-------+";
+ for(int i = 0; i < len; ++i)
+ {
+ const BasicNodeData &v = basicData.at(i);
+ pDebug() << '|' << i
+ << "\t\t|" << v.depth()
+ << "\t|" << v.size()
+ << "\t|" << postNumber(i)
+ << "\t|" << v.kind()
+ << "\t\t|" << (v.name().isNull() ? QString::fromLatin1("(none)") : np->displayName(v.name()))
+ << "\t\t|" << ((v.kind() == QXmlNodeModelIndex::Text && isCompressed(i)) ? CompressedWhitespace::decompress(data.value(i))
+ : data.value(i))
+ << "\t|";
+ /*
+ pDebug() << '|' << QString().arg(i, 14)
+ << '|' << QString().arg(v.depth(), 6)
+ << '|' << QString().arg(v.size(), 6)
+ << '|' << QString().arg(postNumber(i), 14)
+ << '|' << QString().arg(v.kind(), 6)
+ << '|';
+ */
+ }
+ pDebug() << "+---------------+-------+-------+---------------+-------+--------------+";
+ pDebug() << "Namespaces(" << namespaces.count() << "):";
+
+ QHashIterator<PreNumber, QVector<QXmlName> > it(namespaces);
+ while(it.hasNext())
+ {
+ it.next();
+
+ pDebug() << "PreNumber: " << QString::number(it.key());
+ for(int i = 0; i < it.value().count(); ++i)
+ pDebug() << "\t\t" << np->stringForPrefix(it.value().at(i).prefix()) << " = " << np->stringForNamespace(it.value().at(i).namespaceURI());
+ }
+
+#endif
+}
+
+QUrl AccelTree::baseUri(const QXmlNodeModelIndex &ni) const
+{
+ switch(kind(toPreNumber(ni)))
+ {
+ case QXmlNodeModelIndex::Document:
+ return baseUri();
+ case QXmlNodeModelIndex::Element:
+ {
+ const QXmlNodeModelIndex::Iterator::Ptr it(iterate(ni, QXmlNodeModelIndex::AxisAttribute));
+ QXmlNodeModelIndex next(it->next());
+
+ while(!next.isNull())
+ {
+ if(next.name() == QXmlName(StandardNamespaces::xml, StandardLocalNames::base))
+ {
+ const QUrl candidate(next.stringValue());
+ // TODO. The xml:base spec says to do URI escaping here.
+
+ if(!candidate.isValid())
+ return QUrl();
+ else if(candidate.isRelative())
+ {
+ const QXmlNodeModelIndex par(parent(ni));
+
+ if(par.isNull())
+ return baseUri().resolved(candidate);
+ else
+ return par.baseUri().resolved(candidate);
+ }
+ else
+ return candidate;
+ }
+
+ next = it->next();
+ }
+
+ /* We have no xml:base-attribute. Can any parent supply us a base URI? */
+ const QXmlNodeModelIndex par(parent(ni));
+
+ if(par.isNull())
+ return baseUri();
+ else
+ return par.baseUri();
+ }
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Comment:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Attribute:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Text:
+ {
+ const QXmlNodeModelIndex par(ni.iterate(QXmlNodeModelIndex::AxisParent)->next());
+ if(par.isNull())
+ return QUrl();
+ else
+ return par.baseUri();
+ }
+ case QXmlNodeModelIndex::Namespace:
+ return QUrl();
+ }
+
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This line is never supposed to be reached.");
+ return QUrl();
+}
+
+QUrl AccelTree::documentUri(const QXmlNodeModelIndex &ni) const
+{
+ if(kind(toPreNumber(ni)) == QXmlNodeModelIndex::Document)
+ return documentUri();
+ else
+ return QUrl();
+}
+
+QXmlNodeModelIndex::NodeKind AccelTree::kind(const QXmlNodeModelIndex &ni) const
+{
+ return kind(toPreNumber(ni));
+}
+
+QXmlNodeModelIndex::DocumentOrder AccelTree::compareOrder(const QXmlNodeModelIndex &ni1,
+ const QXmlNodeModelIndex &ni2) const
+{
+ Q_ASSERT_X(ni1.model() == ni2.model(), Q_FUNC_INFO,
+ "The API docs guarantees the two nodes are from the same model");
+
+ const PreNumber p1 = ni1.data();
+ const PreNumber p2 = ni2.data();
+
+ if(p1 == p2)
+ return QXmlNodeModelIndex::Is;
+ else if(p1 < p2)
+ return QXmlNodeModelIndex::Precedes;
+ else
+ return QXmlNodeModelIndex::Follows;
+}
+
+QXmlNodeModelIndex AccelTree::root(const QXmlNodeModelIndex &) const
+{
+ return createIndex(qint64(0));
+}
+
+QXmlNodeModelIndex AccelTree::parent(const QXmlNodeModelIndex &ni) const
+{
+ const AccelTree::PreNumber p = basicData.at(toPreNumber(ni)).parent();
+
+ if(p == -1)
+ return QXmlNodeModelIndex();
+ else
+ return createIndex(p);
+}
+
+QXmlNodeModelIndex::Iterator::Ptr AccelTree::iterate(const QXmlNodeModelIndex &ni,
+ QXmlNodeModelIndex::Axis axis) const
+{
+ const PreNumber preNumber = toPreNumber(ni);
+
+ switch(axis)
+ {
+ case QXmlNodeModelIndex::AxisChildOrTop:
+ {
+ if(!hasParent(preNumber))
+ {
+ switch(kind(preNumber))
+ {
+ case QXmlNodeModelIndex::Comment:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Element:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Text:
+ return makeSingletonIterator(ni);
+ case QXmlNodeModelIndex::Attribute:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Document:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Namespace:
+ /* Do nothing. */;
+ }
+ }
+ /* Else, fallthrough to AxisChild. */
+ }
+ case QXmlNodeModelIndex::AxisChild:
+ {
+ if(hasChildren(preNumber))
+ return QXmlNodeModelIndex::Iterator::Ptr(new ChildIterator(this, preNumber));
+ else
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ }
+ case QXmlNodeModelIndex::AxisAncestor:
+ {
+ if(hasParent(preNumber))
+ return QXmlNodeModelIndex::Iterator::Ptr(new AncestorIterator<false>(this, preNumber));
+ else
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ }
+ case QXmlNodeModelIndex::AxisAncestorOrSelf:
+ return QXmlNodeModelIndex::Iterator::Ptr(new AncestorIterator<true>(this, preNumber));
+ case QXmlNodeModelIndex::AxisParent:
+ {
+ if(hasParent(preNumber))
+ return makeSingletonIterator(createIndex(parent(preNumber)));
+ else
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ }
+ case QXmlNodeModelIndex::AxisDescendant:
+ {
+ if(hasChildren(preNumber))
+ return QXmlNodeModelIndex::Iterator::Ptr(new DescendantIterator<false>(this, preNumber));
+ else
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ }
+ case QXmlNodeModelIndex::AxisDescendantOrSelf:
+ return QXmlNodeModelIndex::Iterator::Ptr(new DescendantIterator<true>(this, preNumber));
+ case QXmlNodeModelIndex::AxisFollowing:
+ {
+ if(preNumber == maximumPreNumber())
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ else
+ return QXmlNodeModelIndex::Iterator::Ptr(new FollowingIterator(this, preNumber));
+ }
+ case QXmlNodeModelIndex::AxisAttributeOrTop:
+ {
+ if(!hasParent(preNumber) && kind(preNumber) == QXmlNodeModelIndex::Attribute)
+ return makeSingletonIterator(ni);
+ /* Else, falthrough to AxisAttribute. */
+ }
+ case QXmlNodeModelIndex::AxisAttribute:
+ {
+ if(hasChildren(preNumber) && kind(preNumber + 1) == QXmlNodeModelIndex::Attribute)
+ return QXmlNodeModelIndex::Iterator::Ptr(new AttributeIterator(this, preNumber));
+ else
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ }
+ case QXmlNodeModelIndex::AxisPreceding:
+ {
+ if(preNumber == 0)
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ else
+ return QXmlNodeModelIndex::Iterator::Ptr(new PrecedingIterator(this, preNumber));
+ }
+ case QXmlNodeModelIndex::AxisSelf:
+ return makeSingletonIterator(createIndex(toPreNumber(ni)));
+ case QXmlNodeModelIndex::AxisFollowingSibling:
+ {
+ if(preNumber == maximumPreNumber())
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ else
+ return QXmlNodeModelIndex::Iterator::Ptr(new SiblingIterator<true>(this, preNumber));
+ }
+ case QXmlNodeModelIndex::AxisPrecedingSibling:
+ {
+ if(preNumber == 0)
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ else
+ return QXmlNodeModelIndex::Iterator::Ptr(new SiblingIterator<false>(this, preNumber));
+ }
+ case QXmlNodeModelIndex::AxisNamespace:
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ }
+
+ Q_ASSERT(false);
+ return QXmlNodeModelIndex::Iterator::Ptr();
+}
+
+QXmlNodeModelIndex AccelTree::nextFromSimpleAxis(QAbstractXmlNodeModel::SimpleAxis,
+ const QXmlNodeModelIndex&) const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This function is not supposed to be called.");
+ return QXmlNodeModelIndex();
+}
+
+QVector<QXmlNodeModelIndex> AccelTree::attributes(const QXmlNodeModelIndex &element) const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This function is not supposed to be called.");
+ Q_UNUSED(element);
+ return QVector<QXmlNodeModelIndex>();
+}
+
+QXmlName AccelTree::name(const QXmlNodeModelIndex &ni) const
+{
+ /* If this node type does not have a name(for instance, it's a comment)
+ * we will return the default constructed value, which is conformant with
+ * this function's contract. */
+ return name(toPreNumber(ni));
+}
+
+QVector<QXmlName> AccelTree::namespaceBindings(const QXmlNodeModelIndex &ni) const
+{
+ /* We get a hold of the ancestor, and loop them in reverse document
+ * order(first the parent, then the parent's parent, etc). As soon
+ * we find a binding that hasn't already been added, we add it to the
+ * result list. In that way, declarations appearing further down override
+ * those further up. */
+
+ const PreNumber preNumber = toPreNumber(ni);
+
+ const QXmlNodeModelIndex::Iterator::Ptr it(new AncestorIterator<true>(this, preNumber));
+ QVector<QXmlName> result;
+ QXmlNodeModelIndex n(it->next());
+
+ /* Whether xmlns="" has been encountered. */
+ bool hasUndeclaration = false;
+
+ while(!n.isNull())
+ {
+ const QVector<QXmlName> &forNode = namespaces.value(toPreNumber(n));
+ const int len = forNode.size();
+ bool stopInheritance = false;
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlName &nsb = forNode.at(i);
+
+ if(nsb.namespaceURI() == StandardNamespaces::StopNamespaceInheritance)
+ {
+ stopInheritance = true;
+ continue;
+ }
+
+ if(nsb.prefix() == StandardPrefixes::empty &&
+ nsb.namespaceURI() == StandardNamespaces::empty)
+ {
+ hasUndeclaration = true;
+ continue;
+ }
+
+ if(!hasPrefix(result, nsb.prefix()))
+ {
+ /* We've already encountered an undeclaration, so we're supposed to skip
+ * them. */
+ if(hasUndeclaration && nsb.prefix() == StandardPrefixes::empty)
+ continue;
+ else
+ result.append(nsb);
+ }
+ }
+
+ if(stopInheritance)
+ break;
+ else
+ n = it->next();
+ }
+
+ result.append(QXmlName(StandardNamespaces::xml, StandardLocalNames::empty, StandardPrefixes::xml));
+
+ return result;
+}
+
+void AccelTree::sendNamespaces(const QXmlNodeModelIndex &n,
+ QAbstractXmlReceiver *const receiver) const
+{
+ Q_ASSERT(n.kind() == QXmlNodeModelIndex::Element);
+
+ const QXmlNodeModelIndex::Iterator::Ptr it(iterate(n, QXmlNodeModelIndex::AxisAncestorOrSelf));
+ QXmlNodeModelIndex next(it->next());
+ QVector<QXmlName::PrefixCode> alreadySent;
+
+ while(!next.isNull())
+ {
+ const PreNumber preNumber = toPreNumber(next);
+
+ const QVector<QXmlName> &nss = namespaces.value(preNumber);
+
+ /* This is by far the most common case. */
+ if(nss.isEmpty())
+ {
+ next = it->next();
+ continue;
+ }
+
+ const int len = nss.count();
+ bool stopInheritance = false;
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlName &name = nss.at(i);
+
+ if(name.namespaceURI() == StandardNamespaces::StopNamespaceInheritance)
+ {
+ stopInheritance = true;
+ continue;
+ }
+
+ if(!alreadySent.contains(name.prefix()))
+ {
+ alreadySent.append(name.prefix());
+ receiver->namespaceBinding(name);
+ }
+ }
+
+ if(stopInheritance)
+ break;
+ else
+ next = it->next();
+ }
+}
+
+QString AccelTree::stringValue(const QXmlNodeModelIndex &ni) const
+{
+ const PreNumber preNumber = toPreNumber(ni);
+
+ switch(kind(preNumber))
+ {
+ case QXmlNodeModelIndex::Element:
+ {
+ /* Concatenate all text nodes that are descendants of this node. */
+ if(!hasChildren(preNumber))
+ return QString();
+
+ const AccelTree::PreNumber stop = preNumber + size(preNumber);
+ AccelTree::PreNumber pn = preNumber + 1; /* Jump over ourselves. */
+ QString result;
+
+ for(; pn <= stop; ++pn)
+ {
+ if(kind(pn) == QXmlNodeModelIndex::Text)
+ {
+ if(isCompressed(pn))
+ result += CompressedWhitespace::decompress(data.value(pn));
+ else
+ result += data.value(pn);
+ }
+ }
+
+ return result;
+ }
+ case QXmlNodeModelIndex::Text:
+ {
+ if(isCompressed(preNumber))
+ return CompressedWhitespace::decompress(data.value(preNumber));
+ /* Else, fallthrough. It's not compressed so use it as it is. */
+ }
+ case QXmlNodeModelIndex::Attribute:
+ /* Fallthrough */
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough */
+ case QXmlNodeModelIndex::Comment:
+ return data.value(preNumber);
+ case QXmlNodeModelIndex::Document:
+ {
+ /* Concatenate all text nodes in the whole document. */
+
+ QString result;
+ // Perhaps we can QString::reserve() the result based on the size?
+ const AccelTree::PreNumber max = maximumPreNumber();
+
+ for(AccelTree::PreNumber i = 0; i <= max; ++i)
+ {
+ if(kind(i) == QXmlNodeModelIndex::Text)
+ {
+ if(isCompressed(i))
+ result += CompressedWhitespace::decompress(data.value(i));
+ else
+ result += data.value(i);
+ }
+ }
+
+ return result;
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "A node type that doesn't exist in the XPath Data Model was encountered.");
+ return QString(); /* Dummy, silence compiler warning. */
+ }
+ }
+}
+
+QVariant AccelTree::typedValue(const QXmlNodeModelIndex &n) const
+{
+ return stringValue(n);
+}
+
+bool AccelTree::hasPrefix(const QVector<QXmlName> &nbs, const QXmlName::PrefixCode prefix)
+{
+ const int size = nbs.size();
+
+ for(int i = 0; i < size; ++i)
+ {
+ if(nbs.at(i).prefix() == prefix)
+ return true;
+ }
+
+ return false;
+}
+
+ItemType::Ptr AccelTree::type(const QXmlNodeModelIndex &ni) const
+{
+ /* kind() is manually inlined here to avoid a virtual call. */
+ return XPathHelper::typeFromKind(basicData.at(toPreNumber(ni)).kind());
+}
+
+Item::Iterator::Ptr AccelTree::sequencedTypedValue(const QXmlNodeModelIndex &n) const
+{
+ const PreNumber preNumber = toPreNumber(n);
+
+ switch(kind(preNumber))
+ {
+ case QXmlNodeModelIndex::Element:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Document:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Attribute:
+ return makeSingletonIterator(Item(UntypedAtomic::fromValue(stringValue(n))));
+
+ case QXmlNodeModelIndex::Text:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Comment:
+ return makeSingletonIterator(Item(AtomicString::fromValue(stringValue(n))));
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("A node type that doesn't exist "
+ "in the XPath Data Model was encountered.").arg(kind(preNumber))));
+ return Item::Iterator::Ptr(); /* Dummy, silence compiler warning. */
+ }
+ }
+}
+
+void AccelTree::copyNodeTo(const QXmlNodeModelIndex &node,
+ QAbstractXmlReceiver *const receiver,
+ const NodeCopySettings &settings) const
+{
+ /* This code piece can be seen as a customized version of
+ * QAbstractXmlReceiver::item/sendAsNode(). */
+ Q_ASSERT(receiver);
+ Q_ASSERT(!node.isNull());
+
+ typedef QHash<QXmlName::PrefixCode, QXmlName::NamespaceCode> Binding;
+ QStack<Binding> outputted;
+
+ switch(node.kind())
+ {
+ case QXmlNodeModelIndex::Element:
+ {
+ outputted.push(Binding());
+
+ /* Add the namespace for our element name. */
+ const QXmlName elementName(node.name());
+
+ receiver->startElement(elementName);
+
+ if(!settings.testFlag(InheritNamespaces))
+ receiver->namespaceBinding(QXmlName(StandardNamespaces::StopNamespaceInheritance, 0,
+ StandardPrefixes::StopNamespaceInheritance));
+
+ if(settings.testFlag(PreserveNamespaces))
+ node.sendNamespaces(receiver);
+ else
+ {
+ /* Find the namespaces that we actually use and add them to outputted. These are drawn
+ * from the element name, and the node's attributes. */
+ outputted.top().insert(elementName.prefix(), elementName.namespaceURI());
+
+ const QXmlNodeModelIndex::Iterator::Ptr attributes(iterate(node, QXmlNodeModelIndex::AxisAttribute));
+ QXmlNodeModelIndex attr(attributes->next());
+
+ while(!attr.isNull())
+ {
+ const QXmlName &attrName = attr.name();
+ outputted.top().insert(attrName.prefix(), attrName.namespaceURI());
+ attr = attributes->next();
+ }
+
+ Binding::const_iterator it(outputted.top().constBegin());
+ const Binding::const_iterator end(outputted.top().constEnd());
+
+ for(; it != end; ++it)
+ receiver->namespaceBinding(QXmlName(it.value(), 0, it.key()));
+ }
+
+ /* Send the attributes of the element. */
+ {
+ QXmlNodeModelIndex::Iterator::Ptr attributes(node.iterate(QXmlNodeModelIndex::AxisAttribute));
+ QXmlNodeModelIndex attribute(attributes->next());
+
+ while(!attribute.isNull())
+ {
+ const QString &v = attribute.stringValue();
+ receiver->attribute(attribute.name(), QStringRef(&v));
+ attribute = attributes->next();
+ }
+ }
+
+ /* Send the children of the element. */
+ copyChildren(node, receiver, settings);
+
+ receiver->endElement();
+ outputted.pop();
+ break;
+ }
+ case QXmlNodeModelIndex::Document:
+ {
+ /* We need to intercept and grab the elements of the document node, such
+ * that we preserve/inherit preference applies to them. */
+ receiver->startDocument();
+ copyChildren(node, receiver, settings);
+ receiver->endDocument();
+ break;
+ }
+ default:
+ receiver->item(node);
+ }
+
+}
+
+QSourceLocation AccelTree::sourceLocation(const QXmlNodeModelIndex &index) const
+{
+ const PreNumber key = toPreNumber(index);
+ if (sourcePositions.contains(key)) {
+ const QPair<qint64, qint64> position = sourcePositions.value(key);
+ return QSourceLocation(m_documentURI, position.first, position.second);
+ } else {
+ return QSourceLocation();
+ }
+}
+
+void AccelTree::copyChildren(const QXmlNodeModelIndex &node,
+ QAbstractXmlReceiver *const receiver,
+ const NodeCopySettings &settings) const
+{
+ QXmlNodeModelIndex::Iterator::Ptr children(node.iterate(QXmlNodeModelIndex::AxisChild));
+ QXmlNodeModelIndex child(children->next());
+
+ while(!child.isNull())
+ {
+ copyNodeTo(child, receiver, settings);
+ child = children->next();
+ }
+}
+
+QXmlNodeModelIndex AccelTree::elementById(const QXmlName &id) const
+{
+ const PreNumber pre = m_IDs.value(id.localName(), -1);
+ if(pre == -1)
+ return QXmlNodeModelIndex();
+ else
+ return createIndex(pre);
+}
+
+QVector<QXmlNodeModelIndex> AccelTree::nodesByIdref(const QXmlName &) const
+{
+ return QVector<QXmlNodeModelIndex>();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/acceltree/qacceltree_p.h b/src/xmlpatterns/acceltree/qacceltree_p.h
new file mode 100644
index 0000000..0a9bf6c
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltree_p.h
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AccelTree_H
+#define Patternist_AccelTree_H
+
+#include <QHash>
+#include <QUrl>
+#include <QVector>
+#include <QXmlName>
+
+#include "qitem_p.h"
+#include "qnamepool_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ template<bool> class AccelTreeBuilder;
+
+ /**
+ * @short Stores an XML document using the XPath Accelerator scheme, also
+ * known as pre/post numbering.
+ *
+ * Working on this code will be destructive without a proper understanding of
+ * the Accelerator scheme, so do check out the links. We don't implement any form
+ * of staircase join, although that is only due to time constraints.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @see <a href="http://www.pathfinder-xquery.org/?q=research/xpath-accel">XPath
+ * Accelerator</a>
+ * @see <a href="http://www.pathfinder-xquery.org/files/xpath-accel.pdf">Accelerating
+ * XPath Location Steps, Torsten Grust</a>
+ * @see <a href="http://citeseer.ist.psu.edu/cache/papers/cs/29367/http:zSzzSzwww.informatik.uni-konstanz.dezSz~grustzSzfileszSzstaircase-join.pdf/grust03staircase.pdf">Staircase Join:
+ * Teach a Relational DBMS to Watch its (Axis) Steps</a>
+ * @see <a href="http://ftp.cwi.nl/CWIreports/INS/INS-E0510.pdf">Loop-lifted
+ * staircase join: from XPath to XQuery, Torsten Grust</a>
+ * @see <a href="http://englich.wordpress.com/2007/01/09/xmlstat/">xmlstat, Frans Englich</a>
+ * @see <a href"http://www.inf.uni-konstanz.de/dbis/publications/download/accelerating-locsteps.pdf">Accelerating
+ * XPath Evaluation in Any RDBMS, Torsten Grust</a>
+ */
+ class Q_AUTOTEST_EXPORT AccelTree : public QAbstractXmlNodeModel
+ {
+ friend class AccelTreePrivate;
+ public:
+ using QAbstractXmlNodeModel::createIndex;
+
+ typedef QExplicitlySharedDataPointer<AccelTree> Ptr;
+ typedef qint32 PreNumber;
+ typedef PreNumber PostNumber;
+ typedef qint8 Depth;
+
+ AccelTree(const QUrl &docURI, const QUrl &bURI);
+
+ /**
+ * @short Houses data for a node, and that all node kinds have.
+ *
+ * BasicNodeData is internal to the Accel tree implementation, and is
+ * only used by those classes.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo Can't m_kind be coded somewhere else? If m_name is invalid,
+ * its bits can be used to distinguish the node types that doesn't have
+ * names, and for elements, attributes and processing instructions, we need
+ * two bits, somewhere. Attributes and processing instructions can't have a
+ * size, is that of help? There's also certain rules for the names. For instance,
+ * a processing instruction will never have a prefix nor namespace. Neither
+ * will an attribute node have a default, non-empty namespace, right?
+ * @todo Compress text nodes, add general support for it in Patternist.
+ */
+ class BasicNodeData
+ {
+ public:
+ /* No need to initialize the members. See AccelTreeBuilder. */
+ inline BasicNodeData()
+ {
+ }
+
+ inline BasicNodeData(const PreNumber aDepth,
+ const PreNumber aParent,
+ const QXmlNodeModelIndex::NodeKind k,
+ const PreNumber s,
+ const QXmlName n = QXmlName()) : m_parent(aParent)
+ , m_size(s)
+ , m_name(n)
+ , m_depth(aDepth)
+ , m_kind(k)
+ {
+ }
+
+ inline Depth depth() const
+ {
+ return m_depth;
+ }
+
+ inline PreNumber parent() const
+ {
+ return m_parent;
+ }
+
+ /**
+ * @see AccelTree::size()
+ */
+ inline PreNumber size() const
+ {
+ /* Remember that we use the m_size to signal compression if
+ * we're a text node. */
+ if(m_kind == QXmlNodeModelIndex::Text)
+ return 0;
+ else
+ return m_size;
+ }
+
+ inline void setSize(const PreNumber aSize)
+ {
+ m_size = aSize;
+ }
+
+ inline QXmlNodeModelIndex::NodeKind kind() const
+ {
+ return m_kind;
+ }
+
+ inline QXmlName name() const
+ {
+ return m_name;
+ }
+
+ inline bool isCompressed() const
+ {
+ Q_ASSERT_X(m_kind == QXmlNodeModelIndex::Text, Q_FUNC_INFO,
+ "Currently, only text nodes are compressed.");
+ /* Note, we don't call size() here, since it has logic for text
+ * nodes. */
+ return m_size == IsCompressed;
+ }
+
+ private:
+ /**
+ * This is the pre number of the parent.
+ */
+ PreNumber m_parent;
+
+ /**
+ * This is the count of children this node has.
+ *
+ * In the case of a text node, which cannot have children,
+ * it is set to IsCompressed, if the content has been the result
+ * of CompressedWhitespace::compress(). If it's not compressed,
+ * it is zero.
+ */
+ PreNumber m_size;
+
+ /**
+ * For text nodes, and less importantly, comments,
+ * this variable is not used.
+ */
+ QXmlName m_name;
+
+ Depth m_depth;
+
+ /**
+ * Technically it is sufficient with 7 bits. However, at least MSVC
+ * 2005 miscompiles it such that QXmlNodeModelIndex::Text becomes
+ * -64 instead of 64 with hilarious crashes as result.
+ *
+ * Fortunately this extra bit would be padded anyway.
+ */
+ QXmlNodeModelIndex::NodeKind m_kind : 8;
+ };
+
+ virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const;
+ virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1,
+ const QXmlNodeModelIndex &ni2) const;
+
+ /**
+ * @short Returns the root node.
+ *
+ * This function does not use @p n, so a default constructed
+ * QXmlNodeModelIndex may be passed.
+ */
+ virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const;
+
+ virtual QXmlNodeModelIndex parent(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex::Iterator::Ptr iterate(const QXmlNodeModelIndex &ni,
+ QXmlNodeModelIndex::Axis axis) const;
+ virtual QXmlName name(const QXmlNodeModelIndex &ni) const;
+ virtual QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex &n) const;
+ virtual void sendNamespaces(const QXmlNodeModelIndex &n,
+ QAbstractXmlReceiver *const receiver) const;
+ virtual QString stringValue(const QXmlNodeModelIndex &n) const;
+ virtual QVariant typedValue(const QXmlNodeModelIndex &n) const;
+ virtual Item::Iterator::Ptr sequencedTypedValue(const QXmlNodeModelIndex &n) const;
+ virtual ItemType::Ptr type(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex elementById(const QXmlName &id) const;
+ virtual QVector<QXmlNodeModelIndex> nodesByIdref(const QXmlName &idref) const;
+ virtual void copyNodeTo(const QXmlNodeModelIndex &node,
+ QAbstractXmlReceiver *const receiver,
+ const NodeCopySettings &settings) const;
+
+ friend class AccelTreeBuilder<false>;
+ friend class AccelTreeBuilder<true>;
+
+ enum Constants
+ {
+ IsCompressed = 1
+ };
+
+ /**
+ * The key is the pre number of an element, and the value is a vector
+ * containing the namespace declarations being declared on that
+ * element. Therefore, it does not reflect the namespaces being in
+ * scope for that element. For that, a walk along axis ancestor is
+ * necessary.
+ */
+ QHash<PreNumber, QVector<QXmlName> > namespaces;
+
+ /**
+ * Stores data for nodes. The QHash's value is the data of the processing instruction, and the
+ * content of a text node or comment.
+ */
+ QHash<PreNumber, QString> data;
+
+ QVector<BasicNodeData> basicData;
+ QHash<PreNumber, QPair<qint64, qint64> > sourcePositions;
+
+ inline QUrl documentUri() const
+ {
+ return m_documentURI;
+ }
+
+ inline QUrl baseUri() const
+ {
+ return m_baseURI;
+ }
+
+ /**
+ * @short Returns @c true if the node identified by @p pre has child
+ * nodes(in the sense of the XDM), but also if it has namespace nodes,
+ * or attribute nodes.
+ */
+ inline bool hasChildren(const PreNumber pre) const
+ {
+ return basicData.at(pre).size() > 0;
+ }
+
+ /**
+ * @short Returns the parent node of @p pre.
+ *
+ * If @p pre parent doesn't have a parent node, the return value is
+ * undefined.
+ *
+ * @see hasParent()
+ */
+ inline PreNumber parent(const PreNumber pre) const
+ {
+ return basicData.at(pre).parent();
+ }
+
+ inline bool hasParent(const PreNumber pre) const
+ {
+ return basicData.at(pre).depth() > 0;
+ }
+
+ inline bool hasFollowingSibling(const PreNumber pre) const
+ {
+ return pre < maximumPreNumber();
+ }
+
+ inline PostNumber postNumber(const PreNumber pre) const
+ {
+ const BasicNodeData &b = basicData.at(pre);
+ return pre + b.size() - b.depth();
+ }
+
+ inline QXmlNodeModelIndex::NodeKind kind(const PreNumber pre) const
+ {
+ return basicData.at(pre).kind();
+ }
+
+ inline PreNumber maximumPreNumber() const
+ {
+ return basicData.count() - 1;
+ }
+
+ inline PreNumber toPreNumber(const QXmlNodeModelIndex n) const
+ {
+ return n.data();
+ }
+
+ inline PreNumber size(const PreNumber pre) const
+ {
+ Q_ASSERT_X(basicData.at(pre).size() != -1, Q_FUNC_INFO,
+ "The size cannot be -1. That means an uninitialized value is attempted to be used.");
+ return basicData.at(pre).size();
+ }
+
+ inline Depth depth(const PreNumber pre) const
+ {
+ return basicData.at(pre).depth();
+ }
+
+ void printStats(const NamePool::Ptr &np) const;
+
+ inline QXmlName name(const PreNumber pre) const
+ {
+ return basicData.at(pre).name();
+ }
+
+ inline bool isCompressed(const PreNumber pre) const
+ {
+ return basicData.at(pre).isCompressed();
+ }
+
+ static inline bool hasPrefix(const QVector<QXmlName> &nbs, const QXmlName::PrefixCode prefix);
+
+ QUrl m_documentURI;
+ QUrl m_baseURI;
+
+ protected:
+ virtual QXmlNodeModelIndex nextFromSimpleAxis(QAbstractXmlNodeModel::SimpleAxis,
+ const QXmlNodeModelIndex&) const;
+ virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex &element) const;
+
+ private:
+ /**
+ * Returns the source location for the object with the given @p index.
+ */
+ QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * Copies the children of @p node to @p receiver.
+ */
+ inline void copyChildren(const QXmlNodeModelIndex &node,
+ QAbstractXmlReceiver *const receiver,
+ const NodeCopySettings &settings) const;
+
+ /**
+ * The key is the xml:id value, and the value is the element
+ * with that value.
+ */
+ QHash<QXmlName::LocalNameCode, PreNumber> m_IDs;
+ };
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::AccelTree::BasicNodeData, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/acceltree/qacceltreebuilder.cpp b/src/xmlpatterns/acceltree/qacceltreebuilder.cpp
new file mode 100644
index 0000000..e752632
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreebuilder.cpp
@@ -0,0 +1,440 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qacceltreebuilder_p.h.
+ * If you need includes in this file, put them in qacceltreebuilder_p.h, outside of the namespace.
+ */
+
+template <bool FromDocument>
+AccelTreeBuilder<FromDocument>::AccelTreeBuilder(const QUrl &docURI,
+ const QUrl &baseURI,
+ const NamePool::Ptr &np,
+ ReportContext *const context,
+ Features features) : m_preNumber(-1)
+ , m_isPreviousAtomic(false)
+ , m_hasCharacters(false)
+ , m_isCharactersCompressed(false)
+ , m_namePool(np)
+ , m_document(new AccelTree(docURI, baseURI))
+ , m_skippedDocumentNodes(0)
+ , m_documentURI(docURI)
+ , m_context(context)
+ , m_features(features)
+{
+ Q_ASSERT(m_namePool);
+
+ /* TODO Perhaps we can merge m_ancestors and m_size
+ * into one, and store a struct for the two instead? */
+ m_ancestors.reserve(DefaultNodeStackSize);
+ m_ancestors.push(-1);
+
+ m_size.reserve(DefaultNodeStackSize);
+ m_size.push(0);
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::startStructure()
+{
+ if(m_hasCharacters)
+ {
+ /* We create a node even if m_characters is empty.
+ * Remember that `text {""}' creates one text node
+ * with string value "". */
+
+ ++m_preNumber;
+ m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(),
+ currentParent(),
+ QXmlNodeModelIndex::Text,
+ m_isCharactersCompressed ? AccelTree::IsCompressed : 0));
+ m_document->data.insert(m_preNumber, m_characters);
+ ++m_size.top();
+
+ m_characters.clear(); /* We don't want it added twice. */
+ m_hasCharacters = false;
+
+ if(m_isCharactersCompressed)
+ m_isCharactersCompressed = false;
+ }
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::item(const Item &it)
+{
+ Q_ASSERT(it);
+
+ if(it.isAtomicValue())
+ {
+ if(m_isPreviousAtomic)
+ {
+ m_characters += QLatin1Char(' ');
+ m_characters += it.stringValue();
+ }
+ else
+ {
+ m_isPreviousAtomic = true;
+ const QString sv(it.stringValue());
+
+ if(!sv.isEmpty())
+ {
+ m_characters += sv;
+ m_hasCharacters = true;
+ }
+ }
+ }
+ else
+ sendAsNode(it);
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::startElement(const QXmlName &name)
+{
+ startElement(name, 1, 1);
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::startElement(const QXmlName &name, qint64 line, qint64 column)
+{
+ startStructure();
+
+ AccelTree::BasicNodeData data(currentDepth(), currentParent(), QXmlNodeModelIndex::Element, -1, name);
+ m_document->basicData.append(data);
+ if (m_features & SourceLocationsFeature)
+ m_document->sourcePositions.insert(m_document->maximumPreNumber(), qMakePair(line, column));
+
+ ++m_preNumber;
+ m_ancestors.push(m_preNumber);
+
+ ++m_size.top();
+ m_size.push(0);
+
+ /* With node constructors, we can receive names for which we have no namespace
+ * constructors, such as in the query '<xs:space/>'. Since the 'xs' prefix has no
+ * NamespaceConstructor in this case, we synthesize the namespace.
+ *
+ * In case we're constructing from an XML document we avoid the call because
+ * although it's redundant, it's on extra virtual call for each element. */
+ if(!FromDocument)
+ namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix()));
+
+ m_isPreviousAtomic = false;
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::endElement()
+{
+ startStructure();
+ const AccelTree::PreNumber index = m_ancestors.pop();
+ AccelTree::BasicNodeData &data = m_document->basicData[index];
+
+ /* Sub trees needs to be included in upper trees, so we add the count of this element
+ * to our parent. */
+ m_size[m_size.count() - 2] += m_size.top();
+
+ data.setSize(m_size.pop());
+ m_isPreviousAtomic = false;
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::attribute(const QXmlName &name, const QStringRef &value)
+{
+ /* Attributes adds a namespace binding, so lets synthesize one.
+ *
+ * We optimize by checking whether we have a namespace for which a binding would
+ * be generated. Happens relatively rarely. */
+ if(name.hasPrefix())
+ namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix()));
+
+ m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Attribute, 0, name));
+ ++m_preNumber;
+ ++m_size.top();
+
+ m_isPreviousAtomic = false;
+
+ if(name.namespaceURI() == StandardNamespaces::xml && name.localName() == StandardLocalNames::id)
+ {
+ const QString normalized(value.toString().simplified());
+
+ if(QXmlUtils::isNCName(normalized))
+ {
+ const QXmlName::LocalNameCode id = m_namePool->allocateLocalName(normalized);
+
+ const int oldSize = m_document->m_IDs.count();
+ m_document->m_IDs.insert(id, currentParent());
+ /* We don't run the value through m_attributeCompress here, because
+ * the likelyhood of it deing identical to another attribute is
+ * very small. */
+ m_document->data.insert(m_preNumber, normalized);
+
+ /**
+ * In the case that we're called for doc-available(), m_context is
+ * null, and we need to flag somehow that we failed to load this
+ * document.
+ */
+ if(oldSize == m_document->m_IDs.count() && m_context) // TODO
+ {
+ Q_ASSERT(m_context);
+ m_context->error(QtXmlPatterns::tr("An %1-attribute with value %2 has already been declared.")
+ .arg(formatKeyword("xml:id"),
+ formatData(normalized)),
+ FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091,
+ this);
+ }
+ }
+ else if(m_context) // TODO
+ {
+ Q_ASSERT(m_context);
+
+ /* If we're building from an XML Document(e.g, we're fed from QXmlStreamReader, we raise FODC0002,
+ * otherwise XQDY0091. */
+ m_context->error(QtXmlPatterns::tr("An %1-attribute must have a "
+ "valid %2 as value, which %3 isn't.").arg(formatKeyword("xml:id"),
+ formatType(m_namePool, BuiltinTypes::xsNCName),
+ formatData(value.toString())),
+ FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091,
+ this);
+ }
+ }
+ else
+ m_document->data.insert(m_preNumber, *m_attributeCompress.insert(value.toString()));
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::characters(const QStringRef &ch)
+{
+
+ /* If a text node constructor appears by itself, a node needs to
+ * be created. Therefore, we set m_hasCharacters
+ * if we're the only node.
+ * However, if the text node appears as a child of a document or element
+ * node it is discarded if it's empty.
+ */
+ if(m_hasCharacters && m_isCharactersCompressed)
+ {
+ m_characters = CompressedWhitespace::decompress(m_characters);
+ m_isCharactersCompressed = false;
+ }
+
+ m_characters += ch;
+
+ m_isPreviousAtomic = false;
+ m_hasCharacters = !m_characters.isEmpty() || m_preNumber == -1; /* -1 is our start value. */
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::whitespaceOnly(const QStringRef &ch)
+{
+ Q_ASSERT(!ch.isEmpty());
+ Q_ASSERT(ch.toString().trimmed().isEmpty());
+
+ /* This gets problematic due to how QXmlStreamReader works(which
+ * is the only one we get whitespaceOnly() events from). Namely, text intermingled
+ * with CDATA gets reported as individual Characters events, and
+ * QXmlStreamReader::isWhitespace() can return differently for each of those. However,
+ * it will occur very rarely, so this workaround of 1) mistakenly compressing 2) decompressing 3)
+ * appending, will happen infrequently.
+ */
+ if(m_hasCharacters)
+ {
+ if(m_isCharactersCompressed)
+ {
+ m_characters = CompressedWhitespace::decompress(m_characters);
+ m_isCharactersCompressed = false;
+ }
+
+ m_characters.append(ch.toString());
+ }
+ else
+ {
+ /* We haven't received a text node previously. */
+ m_characters = CompressedWhitespace::compress(ch);
+ m_isCharactersCompressed = true;
+ m_isPreviousAtomic = false;
+ m_hasCharacters = true;
+ }
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::processingInstruction(const QXmlName &target,
+ const QString &data)
+{
+ startStructure();
+ ++m_preNumber;
+ m_document->data.insert(m_preNumber, data);
+
+ m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(),
+ currentParent(),
+ QXmlNodeModelIndex::ProcessingInstruction,
+ 0,
+ target));
+ ++m_size.top();
+ m_isPreviousAtomic = false;
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::comment(const QString &content)
+{
+ startStructure();
+ m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Comment, 0));
+ ++m_preNumber;
+ m_document->data.insert(m_preNumber, content);
+ ++m_size.top();
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::namespaceBinding(const QXmlName &nb)
+{
+ /* Note, because attribute() sometimes generate namespaceBinding() calls, this function
+ * can be called after attributes, in contrast to what the class documentation says. This is ok,
+ * as long as we're not dealing with public API. */
+
+ /* If we've received attributes, it means the element's size have changed and m_preNumber have advanced,
+ * so "reverse back" to the actual element. */
+ const AccelTree::PreNumber pn = m_preNumber - m_size.top();
+
+ QVector<QXmlName> &nss = m_document->namespaces[pn];
+
+ /* "xml" hasn't been declared for each node, AccelTree::namespaceBindings() adds it, so avoid it
+ * such that we don't get duplicates. */
+ if(nb.prefix() == StandardPrefixes::xml)
+ return;
+
+ /* If we already have the binding, skip it. */
+ const int len = nss.count();
+ for(int i = 0; i < len; ++i)
+ {
+ if(nss.at(i).prefix() == nb.prefix())
+ return;
+ }
+
+ nss.append(nb);
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::startDocument()
+{
+ /* If we have already received nodes, we can't add a document node. */
+ if(m_preNumber == -1) /* -1 is our start value. */
+ {
+ m_size.push(0);
+ m_document->basicData.append(AccelTree::BasicNodeData(0, -1, QXmlNodeModelIndex::Document, -1));
+ ++m_preNumber;
+ m_ancestors.push(m_preNumber);
+ }
+ else
+ ++m_skippedDocumentNodes;
+
+ m_isPreviousAtomic = false;
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::endDocument()
+{
+ if(m_skippedDocumentNodes == 0)
+ {
+ /* Create text nodes, if we've received any. We do this only if we're the
+ * top node because if we're getting this event as being a child of an element,
+ * text nodes or atomic values can appear after us, and which must get
+ * merged with the previous text.
+ *
+ * We call startStructure() before we pop the ancestor, such that the text node becomes
+ * a child of this document node. */
+ startStructure();
+
+ m_document->basicData.first().setSize(m_size.pop());
+ m_ancestors.pop();
+ }
+ else
+ --m_skippedDocumentNodes;
+
+ m_isPreviousAtomic = false;
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::atomicValue(const QVariant &value)
+{
+ Q_UNUSED(value);
+ // TODO
+}
+
+template <bool FromDocument>
+QAbstractXmlNodeModel::Ptr AccelTreeBuilder<FromDocument>::builtDocument()
+{
+ /* Create a text node, if we have received text in some way. */
+ startStructure();
+ m_document->printStats(m_namePool);
+
+ return m_document;
+}
+
+template <bool FromDocument>
+NodeBuilder::Ptr AccelTreeBuilder<FromDocument>::create(const QUrl &baseURI) const
+{
+ Q_UNUSED(baseURI);
+ return NodeBuilder::Ptr(new AccelTreeBuilder(QUrl(), baseURI, m_namePool, m_context));
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::startOfSequence()
+{
+}
+
+template <bool FromDocument>
+void AccelTreeBuilder<FromDocument>::endOfSequence()
+{
+}
+
+template <bool FromDocument>
+const SourceLocationReflection *AccelTreeBuilder<FromDocument>::actualReflection() const
+{
+ return this;
+}
+
+template <bool FromDocument>
+QSourceLocation AccelTreeBuilder<FromDocument>::sourceLocation() const
+{
+ if(m_documentURI.isEmpty())
+ return QSourceLocation(QUrl(QLatin1String("AnonymousNodeTree")));
+ else
+ return QSourceLocation(m_documentURI);
+}
+
diff --git a/src/xmlpatterns/acceltree/qacceltreebuilder_p.h b/src/xmlpatterns/acceltree/qacceltreebuilder_p.h
new file mode 100644
index 0000000..747099f
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreebuilder_p.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AccelTreeBuilder_H
+#define Patternist_AccelTreeBuilder_H
+
+#include <QSet>
+#include <QStack>
+
+#include "private/qxmlutils_p.h"
+#include "qacceltree_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcompressedwhitespace_p.h"
+#include "qnamepool_p.h"
+#include "qnodebuilder_p.h"
+#include "qreportcontext_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qpatternistlocale_p.h"
+#include <QtDebug>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Builds an AccelTree from a stream of XML/Item events
+ * received through the NodeBuilder interface.
+ *
+ * If FromDocument is @c true, it is assumed that AccelTreeBuilder is fed
+ * events from an XML document, otherwise it is assumed the events
+ * are from node constructor expressions.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<bool FromDocument>
+ class AccelTreeBuilder : public NodeBuilder
+ , public SourceLocationReflection
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AccelTreeBuilder> Ptr;
+
+ /**
+ * Describes the memory relevant features the builder shall support.
+ */
+ enum Feature
+ {
+ NoneFeature, ///< No special features are enabled.
+ SourceLocationsFeature = 1 ///< The accel tree builder will store source locations for each start element.
+ };
+ Q_DECLARE_FLAGS(Features, Feature)
+
+ /**
+ * @param context may be @c null.
+ */
+ AccelTreeBuilder(const QUrl &docURI,
+ const QUrl &baseURI,
+ const NamePool::Ptr &np,
+ ReportContext *const context,
+ Features features = NoneFeature);
+ virtual void startDocument();
+ virtual void endDocument();
+ virtual void startElement(const QXmlName &name);
+ void startElement(const QXmlName &name, qint64 line, qint64 column);
+ virtual void endElement();
+ virtual void attribute(const QXmlName &name, const QStringRef &value);
+ virtual void characters(const QStringRef &ch);
+ virtual void whitespaceOnly(const QStringRef &ch);
+ virtual void processingInstruction(const QXmlName &target,
+ const QString &data);
+ virtual void namespaceBinding(const QXmlName &nb);
+ virtual void comment(const QString &content);
+ virtual void item(const Item &it);
+
+ virtual QAbstractXmlNodeModel::Ptr builtDocument();
+ virtual NodeBuilder::Ptr create(const QUrl &baseURI) const;
+ virtual void startOfSequence();
+ virtual void endOfSequence();
+
+ inline AccelTree::Ptr builtDocument() const
+ {
+ return m_document;
+ }
+
+ virtual void atomicValue(const QVariant &value);
+
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual QSourceLocation sourceLocation() const;
+
+ private:
+ inline void startStructure();
+
+ inline AccelTree::PreNumber currentDepth() const
+ {
+ return m_ancestors.count() -1;
+ }
+
+ inline AccelTree::PreNumber currentParent() const
+ {
+ return m_ancestors.isEmpty() ? -1 : m_ancestors.top();
+ }
+
+ enum Constants
+ {
+ DefaultNodeStackSize = 10,
+ SizeIsEmpty = 0
+ };
+
+ AccelTree::PreNumber m_preNumber;
+ bool m_isPreviousAtomic;
+ bool m_hasCharacters;
+ /**
+ * Whether m_characters has been run through
+ * CompressedWhitespace::compress().
+ */
+ bool m_isCharactersCompressed;
+ QString m_characters;
+ NamePool::Ptr m_namePool;
+ AccelTree::Ptr m_document;
+ QStack<AccelTree::PreNumber> m_ancestors;
+ QStack<AccelTree::PreNumber> m_size;
+
+ /** If we have already commenced a document, we don't want to
+ * add more document nodes. We keep track of them with this
+ * counter, which ensures that startDocument() and endDocument()
+ * are skipped consistently. */
+ AccelTree::PreNumber m_skippedDocumentNodes;
+
+ /**
+ * All attribute values goes through this set such that we store only
+ * one QString for identical attribute values.
+ */
+ QSet<QString> m_attributeCompress;
+ const QUrl m_documentURI;
+ /**
+ * We don't store a reference pointer here because then we get a
+ * circular reference with GenericDynamicContext, when it stores us as
+ * a member.
+ */
+ ReportContext *const m_context;
+
+ Features m_features;
+ };
+
+ Q_DECLARE_OPERATORS_FOR_FLAGS(AccelTreeBuilder<true>::Features)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(AccelTreeBuilder<false>::Features)
+
+#include "qacceltreebuilder.cpp"
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp
new file mode 100644
index 0000000..4fbfb65
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp
@@ -0,0 +1,441 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTimer>
+#include <QtCore/QXmlStreamReader>
+
+#include <QtNetwork/QNetworkRequest>
+
+#include "qatomicstring_p.h"
+#include "qautoptr_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "qacceltreeresourceloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AccelTreeResourceLoader::AccelTreeResourceLoader(const NamePool::Ptr &np,
+ const NetworkAccessDelegator::Ptr &manager,
+ AccelTreeBuilder<true>::Features features)
+ : m_namePool(np)
+ , m_networkAccessDelegator(manager)
+ , m_features(features)
+{
+ Q_ASSERT(m_namePool);
+ Q_ASSERT(m_networkAccessDelegator);
+}
+
+bool AccelTreeResourceLoader::retrieveDocument(const QUrl &uri,
+ const ReportContext::Ptr &context)
+{
+ Q_ASSERT(uri.isValid());
+ AccelTreeBuilder<true> builder(uri, uri, m_namePool, context.data(), m_features);
+
+ const AutoPtr<QNetworkReply> reply(load(uri, m_networkAccessDelegator, context));
+
+ if(!reply)
+ return false;
+
+ bool success = false;
+ success = streamToReceiver(reply.data(), &builder, m_namePool, context, uri);
+
+ m_loadedDocuments.insert(uri, builder.builtDocument());
+ return success;
+}
+
+bool AccelTreeResourceLoader::retrieveDocument(QIODevice *source, const QUrl &documentUri, const ReportContext::Ptr &context)
+{
+ Q_ASSERT(source);
+ Q_ASSERT(source->isReadable());
+ Q_ASSERT(documentUri.isValid());
+
+ AccelTreeBuilder<true> builder(documentUri, documentUri, m_namePool, context.data(), m_features);
+
+ bool success = false;
+ success = streamToReceiver(source, &builder, m_namePool, context, documentUri);
+
+ m_loadedDocuments.insert(documentUri, builder.builtDocument());
+
+ return success;
+}
+
+QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri,
+ const NetworkAccessDelegator::Ptr &networkDelegator,
+ const ReportContext::Ptr &context, ErrorHandling errorHandling)
+{
+ return load(uri,
+ networkDelegator->managerFor(uri),
+ context, errorHandling);
+}
+
+QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri,
+ QNetworkAccessManager *const networkManager,
+ const ReportContext::Ptr &context, ErrorHandling errorHandling)
+
+{
+ Q_ASSERT(networkManager);
+ Q_ASSERT(uri.isValid());
+
+ NetworkLoop networkLoop;
+
+ QNetworkRequest request(uri);
+ QNetworkReply *const reply = networkManager->get(request);
+ networkLoop.connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(error(QNetworkReply::NetworkError)));
+ networkLoop.connect(reply, SIGNAL(finished()), SLOT(finished()));
+
+ if(networkLoop.exec(QEventLoop::ExcludeUserInputEvents))
+ {
+ const QString errorMessage(escape(reply->errorString()));
+
+ /* Note, we delete reply before we exit this function with error(). */
+ delete reply;
+
+ const QSourceLocation location(uri);
+
+ if(context && (errorHandling == FailOnError))
+ context->error(errorMessage, ReportContext::FODC0002, location);
+
+ return 0;
+ }
+ else
+ return reply;
+}
+
+bool AccelTreeResourceLoader::streamToReceiver(QIODevice *const dev,
+ AccelTreeBuilder<true> *const receiver,
+ const NamePool::Ptr &np,
+ const ReportContext::Ptr &context,
+ const QUrl &uri)
+{
+ Q_ASSERT(dev);
+ Q_ASSERT(receiver);
+ Q_ASSERT(np);
+
+ QXmlStreamReader reader(dev);
+
+ /* Optimize: change NamePool to take QStringRef such that we don't have to call toString() below. That
+ * will save us a gazillion of temporary QStrings. */
+
+ while(!reader.atEnd())
+ {
+ reader.readNext();
+
+ switch(reader.tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ /* Send the name. */
+ receiver->startElement(np->allocateQName(reader.namespaceUri().toString(), reader.name().toString(),
+ reader.prefix().toString()), reader.lineNumber(), reader.columnNumber());
+
+ /* Send namespace declarations. */
+ const QXmlStreamNamespaceDeclarations &nss = reader.namespaceDeclarations();
+
+ /* The far most common case, is for it to be empty. */
+ if(!nss.isEmpty())
+ {
+ const int len = nss.size();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamNamespaceDeclaration &ns = nss.at(i);
+ receiver->namespaceBinding(np->allocateBinding(ns.prefix().toString(), ns.namespaceUri().toString()));
+ }
+ }
+
+ /* Send attributes. */
+ const QXmlStreamAttributes &attrs = reader.attributes();
+ const int len = attrs.size();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamAttribute &attr = attrs.at(i);
+
+ receiver->attribute(np->allocateQName(attr.namespaceUri().toString(), attr.name().toString(),
+ attr.prefix().toString()),
+ attr.value());
+ }
+
+ continue;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ receiver->endElement();
+ continue;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ if(reader.isWhitespace())
+ receiver->whitespaceOnly(reader.text());
+ else
+ receiver->characters(reader.text());
+
+ continue;
+ }
+ case QXmlStreamReader::Comment:
+ {
+ receiver->comment(reader.text().toString());
+ continue;
+ }
+ case QXmlStreamReader::ProcessingInstruction:
+ {
+ receiver->processingInstruction(np->allocateQName(QString(), reader.processingInstructionTarget().toString()),
+ reader.processingInstructionData().toString());
+ continue;
+ }
+ case QXmlStreamReader::StartDocument:
+ {
+ receiver->startDocument();
+ continue;
+ }
+ case QXmlStreamReader::EndDocument:
+ {
+ receiver->endDocument();
+ continue;
+ }
+ case QXmlStreamReader::EntityReference:
+ /* Fallthrough. */
+ case QXmlStreamReader::DTD:
+ {
+ /* We just ignore any DTD and entity references. */
+ continue;
+ }
+ case QXmlStreamReader::Invalid:
+ {
+ if(context)
+ context->error(escape(reader.errorString()), ReportContext::FODC0002, QSourceLocation(uri, reader.lineNumber(), reader.columnNumber()));
+
+ return false;
+ }
+ case QXmlStreamReader::NoToken:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "This token is never expected to be received.");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+Item AccelTreeResourceLoader::openDocument(const QUrl &uri,
+ const ReportContext::Ptr &context)
+{
+ const AccelTree::Ptr doc(m_loadedDocuments.value(uri));
+
+ if(doc)
+ return doc->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */
+ else
+ {
+ if(retrieveDocument(uri, context))
+ return m_loadedDocuments.value(uri)->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */
+ else
+ return Item();
+ }
+}
+
+Item AccelTreeResourceLoader::openDocument(QIODevice *source, const QUrl &documentUri,
+ const ReportContext::Ptr &context)
+{
+ const AccelTree::Ptr doc(m_loadedDocuments.value(documentUri));
+
+ if(doc)
+ return doc->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */
+ else
+ {
+ if(retrieveDocument(source, documentUri, context))
+ return m_loadedDocuments.value(documentUri)->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */
+ else
+ return Item();
+ }
+}
+
+SequenceType::Ptr AccelTreeResourceLoader::announceDocument(const QUrl &uri, const Usage)
+{
+ // TODO deal with the usage thingy
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+
+ return CommonSequenceTypes::ZeroOrOneDocumentNode;
+}
+
+bool AccelTreeResourceLoader::isDocumentAvailable(const QUrl &uri)
+{
+ return retrieveDocument(uri, ReportContext::Ptr());
+}
+
+static inline uint qHash(const QPair<QUrl, QString> &desc)
+{
+ /* Probably a lousy hash. */
+ return qHash(desc.first) + qHash(desc.second);
+}
+
+bool AccelTreeResourceLoader::retrieveUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where)
+{
+ const AutoPtr<QNetworkReply> reply(load(uri, m_networkAccessDelegator, context));
+
+ if(!reply)
+ return false;
+
+ const QTextCodec * codec;
+ if(encoding.isEmpty())
+ {
+ /* XSL Transformations (XSLT) Version 2.0 16.2 Reading Text Files:
+ *
+ * "if the media type of the resource is text/xml or application/xml
+ * (see [RFC2376]), or if it matches the conventions text/\*+xml or
+ * application/\*+xml (see [RFC3023] and/or its successors), then the
+ * encoding is recognized as specified in [XML 1.0]"
+ */
+ codec = QTextCodec::codecForMib(106);
+ }
+ else
+ {
+ codec = QTextCodec::codecForName(encoding.toLatin1());
+ if(codec && context)
+ {
+ context->error(QtXmlPatterns::tr("%1 is an unsupported encoding.").arg(formatURI(encoding)),
+ ReportContext::XTDE1190,
+ where);
+ }
+ else
+ return false;
+ }
+
+ QTextCodec::ConverterState converterState;
+ const QByteArray inData(reply->readAll());
+ const QString result(codec->toUnicode(inData.constData(), inData.length(), &converterState));
+
+ if(converterState.invalidChars)
+ {
+ if(context)
+ {
+ context->error(QtXmlPatterns::tr("%1 contains octets which are disallowed in "
+ "the requested encoding %2.").arg(formatURI(uri),
+ formatURI(encoding)),
+ ReportContext::XTDE1190,
+ where);
+ }
+ else
+ return false;
+ }
+
+ const int len = result.length();
+ /* This code is a candidate for threading. Divide and conqueror. */
+ for(int i = 0; i < len; ++i)
+ {
+ if(!QXmlUtils::isChar(result.at(i)))
+ {
+ if(context)
+ {
+ context->error(QtXmlPatterns::tr("The codepoint %1, occurring in %2 using encoding %3, "
+ "is an invalid XML character.").arg(formatData(result.at(i)),
+ formatURI(uri),
+ formatURI(encoding)),
+ ReportContext::XTDE1190,
+ where);
+ }
+ else
+ return false;
+ }
+ }
+
+ m_unparsedTexts.insert(qMakePair(uri, encoding), result);
+ return true;
+}
+
+bool AccelTreeResourceLoader::isUnparsedTextAvailable(const QUrl &uri,
+ const QString &encoding)
+{
+ return retrieveUnparsedText(uri, encoding, ReportContext::Ptr(), 0);
+}
+
+Item AccelTreeResourceLoader::openUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where)
+{
+ const QString &text = m_unparsedTexts.value(qMakePair(uri, encoding));
+
+ if(text.isNull())
+ {
+ if(retrieveUnparsedText(uri, encoding, context, where))
+ return openUnparsedText(uri, encoding, context, where);
+ else
+ return Item();
+ }
+ else
+ return AtomicString::fromValue(text);
+}
+
+QSet<QUrl> AccelTreeResourceLoader::deviceURIs() const
+{
+ QHash<QUrl, AccelTree::Ptr>::const_iterator it(m_loadedDocuments.constBegin());
+ const QHash<QUrl, AccelTree::Ptr>::const_iterator end(m_loadedDocuments.constEnd());
+ QSet<QUrl> retval;
+
+ while (it != end)
+ {
+ if(it.key().toString().startsWith(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:")))
+ retval.insert(it.key());
+
+ ++it;
+ }
+
+ return retval;
+}
+
+void AccelTreeResourceLoader::clear(const QUrl &uri)
+{
+ m_loadedDocuments.remove(uri);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h b/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h
new file mode 100644
index 0000000..3768ebe
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AccelTreeResourceLoader_H
+#define Patternist_AccelTreeResourceLoader_H
+
+#include <QtCore/QEventLoop>
+#include <QtNetwork/QNetworkReply>
+
+#include "qabstractxmlreceiver.h"
+#include "qacceltree_p.h"
+#include "qacceltreebuilder_p.h"
+#include "qdeviceresourceloader_p.h"
+#include "qnamepool_p.h"
+#include "qnetworkaccessdelegator_p.h"
+#include "qreportcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+
+namespace QPatternist
+{
+ /**
+ * @short An helper class which enables QNetworkAccessManager
+ * to be used in a blocking manner.
+ *
+ * @see AccelTreeResourceLoader::load()
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NetworkLoop : public QEventLoop
+ {
+ Q_OBJECT
+ public:
+ NetworkLoop() : m_hasReceivedError(false)
+ {
+ }
+
+ public Q_SLOTS:
+ void error(QNetworkReply::NetworkError code)
+ {
+ Q_UNUSED(code);
+ m_hasReceivedError = true;
+ exit(1);
+ }
+
+ void finished()
+ {
+ if(m_hasReceivedError)
+ exit(1);
+ else
+ exit(0);
+ }
+ private:
+ bool m_hasReceivedError;
+ };
+
+ /**
+ * @short Handles requests for documents, and instantiates
+ * them as AccelTree instances.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT AccelTreeResourceLoader : public DeviceResourceLoader
+ {
+ public:
+ /**
+ * Describes the behaviour of the resource loader in case of an
+ * error.
+ */
+ enum ErrorHandling
+ {
+ FailOnError, ///< The resource loader will report the error via the report context.
+ ContinueOnError ///< The resource loader will report no error and return an empty QNetworkReply.
+ };
+
+ /**
+ * AccelTreeResourceLoader does not own @p context.
+ */
+ AccelTreeResourceLoader(const NamePool::Ptr &np,
+ const NetworkAccessDelegator::Ptr &networkDelegator, AccelTreeBuilder<true>::Features = AccelTreeBuilder<true>::NoneFeature);
+
+ virtual Item openDocument(const QUrl &uri,
+ const ReportContext::Ptr &context);
+ virtual Item openDocument(QIODevice *source, const QUrl &documentUri,
+ const ReportContext::Ptr &context);
+ virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint);
+ virtual bool isDocumentAvailable(const QUrl &uri);
+
+ virtual bool isUnparsedTextAvailable(const QUrl &uri,
+ const QString &encoding);
+
+ virtual Item openUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where);
+
+ /**
+ * @short Helper function that do NetworkAccessDelegator::get(), but
+ * does it blocked.
+ *
+ * The returned QNetworkReply has emitted QNetworkReply::finished().
+ *
+ * The caller owns the return QIODevice instance.
+ *
+ * @p context may be @c null or valid. If @c null, no error reporting
+ * is done and @c null is returned.
+ *
+ * @see NetworkAccessDelegator
+ */
+ static QNetworkReply *load(const QUrl &uri,
+ QNetworkAccessManager *const networkManager,
+ const ReportContext::Ptr &context, ErrorHandling handling = FailOnError);
+
+ /**
+ * @overload
+ */
+ static QNetworkReply *load(const QUrl &uri,
+ const NetworkAccessDelegator::Ptr &networkDelegator,
+ const ReportContext::Ptr &context, ErrorHandling handling = FailOnError);
+
+ /**
+ * @short Returns the URIs this AccelTreeResourceLoader has loaded
+ * which are for devices through variable bindings.
+ */
+ virtual QSet<QUrl> deviceURIs() const;
+
+ virtual void clear(const QUrl &uri);
+
+ private:
+ static bool streamToReceiver(QIODevice *const dev,
+ AccelTreeBuilder<true> *const receiver,
+ const NamePool::Ptr &np,
+ const ReportContext::Ptr &context,
+ const QUrl &uri);
+ bool retrieveDocument(const QUrl &uri,
+ const ReportContext::Ptr &context);
+ bool retrieveDocument(QIODevice *source, const QUrl &documentUri,
+ const ReportContext::Ptr &context);
+ /**
+ * If @p context is @c null, no error reporting should be done.
+ */
+ bool retrieveUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where);
+
+ QHash<QUrl, AccelTree::Ptr> m_loadedDocuments;
+ const NamePool::Ptr m_namePool;
+ const NetworkAccessDelegator::Ptr m_networkAccessDelegator;
+ QHash<QPair<QUrl, QString>, QString> m_unparsedTexts;
+ AccelTreeBuilder<true>::Features m_features;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/acceltree/qcompressedwhitespace.cpp b/src/xmlpatterns/acceltree/qcompressedwhitespace.cpp
new file mode 100644
index 0000000..16c116c
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qcompressedwhitespace.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+
+#include "qcompressedwhitespace_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CompressedWhitespace::CharIdentifier CompressedWhitespace::toIdentifier(const QChar ch)
+{
+ switch(ch.unicode())
+ {
+ case ' ':
+ return Space;
+ case '\n':
+ return LF;
+ case '\r':
+ return CR;
+ case '\t':
+ return Tab;
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "The caller must guarantee only whitespace is passed.");
+ return Tab;
+ }
+ }
+}
+
+bool CompressedWhitespace::isEven(const int number)
+{
+ Q_ASSERT(number >= 0);
+ return number % 2 == 0;
+}
+
+quint8 CompressedWhitespace::toCompressedChar(const QChar ch, const int len)
+{
+ Q_ASSERT(len > 0);
+ Q_ASSERT(len <= MaxCharCount);
+
+ return len + toIdentifier(ch);
+}
+
+QChar CompressedWhitespace::toChar(const CharIdentifier id)
+{
+ switch(id)
+ {
+ case Space: return QLatin1Char(' ');
+ case CR: return QLatin1Char('\r');
+ case LF: return QLatin1Char('\n');
+ case Tab: return QLatin1Char('\t');
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected input");
+ return QChar();
+ }
+ }
+}
+
+QString CompressedWhitespace::compress(const QStringRef &input)
+{
+ Q_ASSERT(!isEven(1) && isEven(0) && isEven(2));
+ Q_ASSERT(!input.isEmpty());
+
+ QString result;
+ const int len = input.length();
+
+ /* The amount of compressed characters. For instance, if input is
+ * four spaces followed by one tab, compressedChars will be 2, and the resulting
+ * QString will have a length of 1, two compressedChars stored in one QChar. */
+ int compressedChars = 0;
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QChar c(input.at(i));
+
+ int start = i;
+
+ while(true)
+ {
+ if(i + 1 == input.length() || input.at(i + 1) != c)
+ break;
+ else
+ ++i;
+ }
+
+ /* The length of subsequent whitespace characters in the input. */
+ int wsLen = (i - start) + 1;
+
+ /* We might get a sequence of whitespace that is so long, that we can't
+ * store it in one unit/byte. In that case we chop it into as many subsequent
+ * ones that is needed. */
+ while(true)
+ {
+ const int unitLength = qMin(wsLen, int(MaxCharCount));
+ wsLen -= unitLength;
+
+ ushort resultCP = toCompressedChar(c, unitLength);
+
+ if(isEven(compressedChars))
+ result += QChar(resultCP);
+ else
+ {
+ resultCP = resultCP << 8;
+ resultCP |= result.at(result.size() - 1).unicode();
+ result[result.size() - 1] = resultCP;
+ }
+
+ ++compressedChars;
+
+ if(wsLen == 0)
+ break;
+ }
+ }
+
+ return result;
+}
+
+QString CompressedWhitespace::decompress(const QString &input)
+{
+ Q_ASSERT(!input.isEmpty());
+ const int len = input.length() * 2;
+ QString retval;
+
+ for(int i = 0; i < len; ++i)
+ {
+ ushort cp = input.at(i / 2).unicode();
+
+ if(isEven(i))
+ cp &= Lower8Bits;
+ else
+ {
+ cp = cp >> 8;
+
+ if(cp == 0)
+ return retval;
+ }
+
+ const quint8 wsLen = cp & Lower6Bits;
+ const quint8 id = cp & UpperTwoBits;
+
+ /* Resize retval, and fill in on the top. */
+ const int oldSize = retval.size();
+ const int newSize = retval.size() + wsLen;
+ retval.resize(newSize);
+ const QChar ch(toChar(CharIdentifier(id)));
+
+ for(int f = oldSize; f < newSize; ++f)
+ retval[f] = ch;
+ }
+
+ return retval;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/acceltree/qcompressedwhitespace_p.h b/src/xmlpatterns/acceltree/qcompressedwhitespace_p.h
new file mode 100644
index 0000000..859811d
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qcompressedwhitespace_p.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CompressedWhitespace_H
+#define Patternist_CompressedWhitespace_H
+
+#include <QtGlobal>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QChar;
+class QString;
+class QStringRef;
+
+namespace QPatternist
+{
+ /**
+ * @short A compression facility for whitespace nodes.
+ *
+ * CompressedWhitespace compresses and decompresses strings that consists of
+ * whitespace only, and do so with a scheme that is designed to do this
+ * specialized task in an efficient way. The approach is simple: each
+ * sequence of equal whitespace in the input gets coded into one byte,
+ * where the first two bits signals the type, CharIdentifier, and the
+ * remininding six bits is the count.
+ *
+ * For instance, this scheme manages to compress a sequence of spaces
+ * followed by a new line into 16 bits(one QChar), and QString stores
+ * strings of one QChar quite efficiently, by avoiding a heap allocation.
+ *
+ * There is no way to tell whether a QString is compressed or not.
+ *
+ * The compression scheme originates from Saxon, by Michael Kay.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT CompressedWhitespace
+ {
+ public:
+ /**
+ * @short Compresses @p input into a compressed format, returned
+ * as a QString.
+ *
+ * The caller guarantees that input is not empty
+ * and consists only of whitespace.
+ *
+ * The returned format is opaque. There is no way to find out
+ * whether a QString contains compressed data or not.
+ *
+ * @see decompress()
+ */
+ static QString compress(const QStringRef &input);
+
+ /**
+ * @short Decompresses @p input into a usual QString.
+ *
+ * @p input must be a QString as per returned from compress().
+ *
+ * @see compress()
+ */
+ static QString decompress(const QString &input);
+
+ private:
+ /**
+ * We use the two upper bits for communicating what space it is.
+ */
+ enum CharIdentifier
+ {
+ Space = 0x0,
+
+ /**
+ * 0xA, \\r
+ *
+ * Binary: 10000000
+ */
+ CR = 0x80,
+
+ /**
+ * 0xD, \\n
+ *
+ * Binary: 01000000
+ */
+ LF = 0x40,
+
+ /**
+ * Binary: 11000000
+ */
+ Tab = 0xC0
+ };
+
+ enum Constants
+ {
+ /* We can at maximum store this many consecutive characters
+ * of one type. We use 6 bits for the count. */
+ MaxCharCount = (1 << 6) - 1,
+
+ /**
+ * Binary: 11111111
+ */
+ Lower8Bits = (1 << 8) - 1,
+
+ /**
+ * Binary: 111111
+ */
+ Lower6Bits = (1 << 6) - 1,
+
+ /*
+ * Binary: 11000000
+ */
+ UpperTwoBits = 3 << 6
+ };
+
+ static inline CharIdentifier toIdentifier(const QChar ch);
+
+ static inline quint8 toCompressedChar(const QChar ch, const int len);
+ static inline QChar toChar(const CharIdentifier id);
+
+ /**
+ * @short Returns @c true if @p number is an even number, otherwise
+ * @c false.
+ */
+ static inline bool isEven(const int number);
+
+ /**
+ * @short This class can only be used via its static members.
+ */
+ inline CompressedWhitespace();
+ Q_DISABLE_COPY(CompressedWhitespace)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/api.pri b/src/xmlpatterns/api/api.pri
new file mode 100644
index 0000000..a0adf75
--- /dev/null
+++ b/src/xmlpatterns/api/api.pri
@@ -0,0 +1,57 @@
+HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \
+ $$PWD/qabstractmessagehandler.h \
+ $$PWD/qabstracturiresolver.h \
+ $$PWD/qabstractxmlnodemodel.h \
+ $$PWD/qabstractxmlnodemodel_p.h \
+ $$PWD/qabstractxmlpullprovider_p.h \
+ $$PWD/qabstractxmlreceiver.h \
+ $$PWD/qabstractxmlreceiver_p.h \
+ $$PWD/qdeviceresourceloader_p.h \
+ $$PWD/qiodevicedelegate_p.h \
+ $$PWD/qnetworkaccessdelegator_p.h \
+ $$PWD/qpullbridge_p.h \
+ $$PWD/qresourcedelegator_p.h \
+ $$PWD/qsimplexmlnodemodel.h \
+ $$PWD/qsourcelocation.h \
+ $$PWD/quriloader_p.h \
+ $$PWD/qvariableloader_p.h \
+ $$PWD/qxmlformatter.h \
+ $$PWD/qxmlname.h \
+ $$PWD/qxmlnamepool.h \
+ $$PWD/qxmlquery.h \
+ $$PWD/qxmlquery_p.h \
+ $$PWD/qxmlresultitems.h \
+ $$PWD/qxmlresultitems_p.h \
+ $$PWD/qxmlschema.h \
+ $$PWD/qxmlschema_p.h \
+ $$PWD/qxmlschemavalidator.h \
+ $$PWD/qxmlschemavalidator_p.h \
+ $$PWD/qxmlserializer.h \
+ $$PWD/qxmlserializer_p.h \
+ $$PWD/qcoloringmessagehandler_p.h \
+ $$PWD/qcoloroutput_p.h \
+ $$PWD/qxmlpatternistcli_p.h
+SOURCES += $$PWD/qvariableloader.cpp \
+ $$PWD/qabstractmessagehandler.cpp \
+ $$PWD/qabstracturiresolver.cpp \
+ $$PWD/qabstractxmlnodemodel.cpp \
+ $$PWD/qabstractxmlpullprovider.cpp \
+ $$PWD/qabstractxmlreceiver.cpp \
+ $$PWD/qiodevicedelegate.cpp \
+ $$PWD/qnetworkaccessdelegator.cpp \
+ $$PWD/qpullbridge.cpp \
+ $$PWD/qresourcedelegator.cpp \
+ $$PWD/qsimplexmlnodemodel.cpp \
+ $$PWD/qsourcelocation.cpp \
+ $$PWD/quriloader.cpp \
+ $$PWD/qxmlformatter.cpp \
+ $$PWD/qxmlname.cpp \
+ $$PWD/qxmlnamepool.cpp \
+ $$PWD/qxmlquery.cpp \
+ $$PWD/qxmlresultitems.cpp \
+ $$PWD/qxmlschema.cpp \
+ $$PWD/qxmlschema_p.cpp \
+ $$PWD/qxmlschemavalidator.cpp \
+ $$PWD/qxmlserializer.cpp \
+ $$PWD/qcoloringmessagehandler.cpp \
+ $$PWD/qcoloroutput.cpp
diff --git a/src/xmlpatterns/api/qabstractmessagehandler.cpp b/src/xmlpatterns/api/qabstractmessagehandler.cpp
new file mode 100644
index 0000000..63a963b
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractmessagehandler.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QMutex>
+
+#include "private/qobject_p.h"
+#include "qabstractmessagehandler.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractMessageHandlerPrivate : public QObjectPrivate
+{
+public:
+ QMutex mutex;
+};
+
+/*!
+ \class QAbstractMessageHandler
+ \threadsafe
+ \since 4.4
+ \ingroup xml-tools
+
+ \brief The QAbstractMessageHandler class provides a callback interface for handling messages.
+
+ QAbstractMessageHandler is an abstract base class that provides a
+ callback interface for handling messages. For example, class
+ QXmlQuery parses and runs an XQuery. When it detects a compile
+ or runtime error, it generates an appropriate error message,
+ but rather than output the message itself, it passes the message to
+ the message() function of its QAbstractMessageHandler.
+ See QXmlQuery::setMessageHandler().
+
+ You create a message handler by subclassing QAbstractMessageHandler
+ and implementing handleMessage(). You then pass a pointer to an
+ instance of your subclass to any classes that must generate
+ messages. The messages are sent to the message handler via the
+ message() function, which forwards them to your handleMessge().
+ The effect is to serialize the handling of all messages, which
+ means your QAbstractMessageHandler subclass is thread safe.
+
+ A single instance of QAbstractMessageHandler can be called on to
+ handle messages from multiple sources. Hence, the content of a
+ message, which is the \e description parameter passed to message()
+ and handleMessage(), must be interpreted in light of the context
+ that required the message to be sent. That context is specified by
+ the \e identifier and \e sourceLocation parameters to message()
+ handleMessage().
+ */
+
+/*!
+ Constructs a QAbstractMessageHandler. The \a parent is passed
+ to the QObject base class constructor.
+ */
+QAbstractMessageHandler::QAbstractMessageHandler(QObject *parent) : QObject(*new QAbstractMessageHandlerPrivate(), parent)
+{
+}
+
+/*!
+ Destructs this QAbstractMessageHandler.
+ */
+QAbstractMessageHandler::~QAbstractMessageHandler()
+{
+}
+
+/*!
+ Sends a message to this message handler. \a type is the kind of
+ message being sent. \a description is the message content. The \a
+ identifier is a URI that identifies the message and is the key to
+ interpreting the other arguments.
+
+ Typically, this class is used for reporting errors, as is the case
+ for QXmlQuery, which uses a QAbstractMessageHandler to report
+ compile and runtime XQuery errors. Hence, using a QUrl as the
+ message \a identifier is was inspired by the explanation of \l{error
+ handling in the XQuery language}. Because the \a identifier is
+ composed of a namespace URI and a local part, identifiers with the
+ same local part are unique. The caller is responsible for ensuring
+ that \a identifier is either a valid QUrl or a default constructed
+ QUrl.
+
+ \a sourceLocation identifies a location in a resource (i.e., file or
+ document) where the need for reporting a message was detected.
+
+ This function unconditionally calls handleMessage(), passing all
+ its parameters unmodified.
+
+ \sa {http://www.w3.org/TR/xquery/#errors}
+ */
+void QAbstractMessageHandler::message(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier,
+ const QSourceLocation &sourceLocation)
+{
+ Q_D(QAbstractMessageHandler);
+ QMutexLocker(&d->mutex);
+ handleMessage(type, description, identifier, sourceLocation);
+}
+
+/*!
+ \fn void QAbstractMessageHandler::handleMessage(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier = QUrl(),
+ const QSourceLocation &sourceLocation = QSourceLocation()) = 0
+
+ This function must be implemented by the sub-class. message() will
+ call this function, passing in its parameters, \a type,
+ \a description, \a identifier and \a sourceLocation unmodified.
+ */
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qabstractmessagehandler.h b/src/xmlpatterns/api/qabstractmessagehandler.h
new file mode 100644
index 0000000..a5fe0ff
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractmessagehandler.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMESSAGEHANDLER_H
+#define QABSTRACTMESSAGEHANDLER_H
+
+#include <QtXmlPatterns/QSourceLocation>
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QAbstractMessageHandlerPrivate;
+class Q_XMLPATTERNS_EXPORT QAbstractMessageHandler : public QObject
+{
+ Q_OBJECT
+public:
+ QAbstractMessageHandler(QObject *parent = 0);
+ virtual ~QAbstractMessageHandler();
+
+ void message(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier = QUrl(),
+ const QSourceLocation &sourceLocation = QSourceLocation());
+
+protected:
+ virtual void handleMessage(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier,
+ const QSourceLocation &sourceLocation) = 0;
+private:
+ Q_DECLARE_PRIVATE(QAbstractMessageHandler)
+ Q_DISABLE_COPY(QAbstractMessageHandler)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qabstracturiresolver.cpp b/src/xmlpatterns/api/qabstracturiresolver.cpp
new file mode 100644
index 0000000..baa65b3
--- /dev/null
+++ b/src/xmlpatterns/api/qabstracturiresolver.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qabstracturiresolver.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstractUriResolver
+ \brief The QAbstractUriResolver class is a callback interface for resolving Uniform Resource Identifiers.
+ \since 4.4
+ \reentrant
+ \ingroup xml-tools
+
+ A Uniform Resource Identifier (URI) is a string that uniquely
+ identifies a resource. URIs are versatile global identifiers. It is
+ often useful to transform a URI that identifies something logical
+ into a URI that locates something physical (a URL), or to simply map
+ a URI to a different URI. QAbstractUriResolver::resolve() provides
+ this functionality.
+
+ For example, one could write a QAbstractUriResolver subclass that
+ rewrites library ISBN number URIs as book title URLs, e.g.,
+ \e{urn:isbn:0-345-33973-8} would be rewritten as
+ \e{file:///books/returnOfTheKing.doc}. Or a QAbstractUriResolver
+ subclass could be written for a web browser to let the web browser
+ protect the user's private files by mapping incoming requests for
+ them to null URIs.
+
+ \sa {http://en.wikipedia.org/wiki/Uniform_Resource_Identifier}
+*/
+
+/*!
+ Constructs a QAbstractUriResolver with the specified \a parent.
+ */
+QAbstractUriResolver::QAbstractUriResolver(QObject *parent) : QObject(parent)
+{
+}
+
+/*!
+ Destructor.
+ */
+QAbstractUriResolver::~QAbstractUriResolver()
+{
+}
+
+/*!
+ \fn QUrl QAbstractUriResolver::resolve(const QUrl &relative, const QUrl &baseURI) const
+
+ Returns the \a relative URI resolved using the \a baseURI.
+
+ The caller guarantees that both \a relative and \a baseURI are
+ valid, and that \a baseURI is absolute. \a relative can be relative,
+ absolute, or empty.
+
+ The returned QUrl can be a default constructed QUrl. If it is not a
+ default constructed QUrl, it will be absolute and valid. If a default
+ constructed QUrl is returned, it means the \a relative URI was not
+ accepted to be resolved.
+
+ If the reimplemented resolve() function decides it has nothing to do
+ about resolving the \a relative URI, it should simply return the \a
+ relative URI resolved against the \a baseURI, i.e.:
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp 0
+
+ \sa QUrl::isRelative(), QUrl::isValid()
+ */
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qabstracturiresolver.h b/src/xmlpatterns/api/qabstracturiresolver.h
new file mode 100644
index 0000000..bbe4a90
--- /dev/null
+++ b/src/xmlpatterns/api/qabstracturiresolver.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTURIRESOLVER_H
+#define QABSTRACTURIRESOLVER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QUrl;
+class QAbstractUriResolverPrivate;
+
+class Q_XMLPATTERNS_EXPORT QAbstractUriResolver : public QObject
+{
+ Q_OBJECT
+public:
+ QAbstractUriResolver(QObject *parent = 0);
+ virtual ~QAbstractUriResolver();
+
+ virtual QUrl resolve(const QUrl &relative,
+ const QUrl &baseURI) const = 0;
+
+private:
+ Q_DISABLE_COPY(QAbstractUriResolver)
+ Q_DECLARE_PRIVATE(QAbstractUriResolver)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qabstractxmlforwarditerator.cpp b/src/xmlpatterns/api/qabstractxmlforwarditerator.cpp
new file mode 100644
index 0000000..046b9e4
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlforwarditerator.cpp
@@ -0,0 +1,269 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QAbstractXmlForwardIterator
+ \brief The QAbstractXmlForwardIterator class is a base class for forward iterators.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+ \internal
+
+ This abstract base class is for creating iterators for
+ traversing custom data structures modeled to look like XML.
+ An item can be instantiated in QAbstractXmlForwardIterator if:
+ \list
+
+ \o It has a default constructor, a copy constructor, and an
+ assignment operator, and
+
+ \o It has an appropriate qIsForwardIteratorEnd() function.
+ \endlist
+
+ @ingroup Patternist_iterators
+ @author Frans Englich <frans.englich@nokia.com>
+ */
+
+/*!
+ \typedef QAbstractXmlForwardIterator::Ptr
+
+ A smart pointer wrapping an instance of a QAbstractXmlForwardIterator subclass.
+ */
+
+/*!
+ \typedef QAbstractXmlForwardIterator::List
+ A QList containing QAbstractXmlForwardIterator::Ptr instances.
+ */
+
+/*!
+ \typedef QAbstractXmlForwardIterator::Vector
+ A QVector containing QAbstractXmlForwardIterator::Ptr instances.
+ */
+
+/*!
+ \fn QAbstractXmlForwardIterator::QAbstractXmlForwardIterator()
+
+ Default constructor.
+ */
+
+/*!
+ \fn QAbstractXmlForwardIterator::~QAbstractXmlForwardIterator()
+
+ Destructor.
+ */
+
+/*!
+ \fn T QAbstractXmlForwardIterator::next() = 0;
+
+ Returns the next item in the sequence, or
+ a null object if the end has been reached.
+ */
+
+/*!
+ \fn T QAbstractXmlForwardIterator::current() const = 0;
+
+ Returns the current item in the sequence. If this function is called
+ before the first call to next(), a null object is returned. If the
+ end of the sequence has been reached, a null object is returned.
+ */
+
+/*!
+ \fn qint64 QAbstractXmlForwardIterator::position() const = 0;
+
+ Returns the current position in the sequence represented
+ by \e this.
+
+ The first position is 1, not 0. If next() hasn't been called, 0 is
+ returned. If \e this has reached the end, -1 is returned.
+ */
+
+/*!
+ \fn bool qIsForwardIteratorEnd(const T &unit)
+ \since 4.4
+ \relates QAbstractXmlForwardIterator
+
+ The Callback QAbstractXmlForwardIterator uses for determining
+ whether \a unit is the end of a sequence.
+
+ If \a unit is a value that would signal the end of a sequence
+ (typically a default constructed value), this function returns \c
+ true, otherwise \c false.
+
+ This implementation works for any type that has a boolean operator.
+ For example, this function should work satisfactory for pointers.
+ */
+
+/*!
+ \fn qint64 QAbstractXmlForwardIterator::count()
+ \internal
+
+ Determines the number of items this QAbstractXmlForwardIterator
+ represents.
+
+ Note that this function is not \c const. It modifies the
+ QAbstractXmlForwardIterator. The reason for this is efficiency. If
+ this QAbstractXmlForwardIterator must not be changed, get a copy()
+ before performing the count.
+
+ The default implementation simply calls next() until the end is
+ reached. Hence, it may be of interest to override this function if
+ the sub-class knows a better way of computing its count.
+
+ The number of items in the sequence is returned.
+ */
+
+/*!
+ \fn QAbstractXmlForwardIterator<T>::Ptr QAbstractXmlForwardIterator::toReversed();
+ \internal
+
+ Returns a reverse iterator for the sequence.
+
+ This function may modify the iterator, it can be considered a
+ function that evaluates this QAbstractXmlForwardIterator. It is not
+ a \e getter, but potentially alters the iterator in the same way the
+ next() function does. If this QAbstractXmlForwardIterator must not
+ be modified, such that it can be used for evaluation with next(),
+ use a copy().
+ */
+
+/*!
+ \fn QList<T> QAbstractXmlForwardIterator<T>::toList();
+ \internal
+
+ Performs a copy of this QAbstractXmlForwardIterator(with copy()),
+ and returns its items in a QList. Thus, this function acts as a
+ conversion function, converting the sequence to a QList.
+
+ This function may modify the iterator. It is not a \e getter, but
+ potentially alters the iterator in the same way the next() function
+ does. If this QAbstractXmlForwardIterator must not be modified,
+ such that it can be used for evaluation with next(), use a copy().
+ */
+
+/*!
+ \fn T QAbstractXmlForwardIterator::last();
+ \internal
+
+ Returns the item at the end of this QAbstractXmlForwardIterator.
+ The default implementation calls next() until the end is reached.
+ */
+
+/*!
+ \fn T QAbstractXmlForwardIterator::isEmpty();
+ \internal
+ Returns true if the sequence is empty.
+ */
+
+/*!
+ \fn qint64 QAbstractXmlForwardIterator::sizeHint() const;
+ \internal
+
+ Gives a hint to the size of the contained sequence. The hint is
+ assumed to be as close as possible to the actual size.
+
+ If no sensible estimate can be computed, -1 should be returned.
+ */
+
+/*!
+ \fn typename QAbstractXmlForwardIterator<T>::Ptr QAbstractXmlForwardIterator::copy() const;
+ \internal
+
+ Copies this QAbstractXmlForwardIterator and returns the copy.
+
+ A copy and the original instance are completely independent of each
+ other. Because evaluating an QAbstractXmlForwardIterator modifies
+ it, one should always use a copy when an
+ QAbstractXmlForwardIterator needs to be used several times.
+ */
+
+/*!
+ \class QPatternist::ListIteratorPlatform
+ \brief Helper class for ListIterator, and should only be instantiated through sub-classing.
+ \reentrant
+ \since 4.4
+ \internal
+ \ingroup xml-tools
+
+ ListIteratorPlatform iterates an InputList with instances
+ of InputType. For every item in it, it returns an item from it,
+ that is converted to OutputType by calling a function on Derived
+ that has the following signature:
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp 0
+
+ TODO Document why this class doesn't duplicate ItemMappingIterator.
+ */
+
+/*!
+ \fn QPatternist::ListIteratorPlatform::ListIteratorPlatform(const ListType &list);
+
+ Constructs a ListIteratorPlatform that walks the given \a list.
+ */
+
+/*!
+ \class QPatternist::ListIterator
+ \brief Bridges values in Qt's QList container class into an QAbstractXmlForwardIterator.
+ \reentrant
+ \since 4.4
+ \internal
+ \ingroup xml-tools
+
+ ListIterator takes a reference to a QList<T> instance and allows
+ access to that list via its QAbstractXmlForwardIterator interface.
+ ListIterator is parameterized with the type to iterate over, e.g.,
+ Item or Expression::Ptr.
+
+ ListIterator is used by the ExpressionSequence to create an
+ iterator over its operands. The iterator will be passed to a
+ MappingIterator.
+ */
+
+/*!
+ \fn QPatternist::makeListIterator(const QList<T> &qList)
+ \relates QPatternist::ListIterator
+
+ An object generator for ListIterator.
+
+ makeListIterator() is a convenience function to avoid specifying
+ the full template instantiation for ListIterator. Conceptually, it
+ is identical to Qt's qMakePair().
+
+ */
diff --git a/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h b/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h
new file mode 100644
index 0000000..3e222e8
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QABSTRACTXMLFORWARDITERATOR_H
+#define QABSTRACTXMLFORWARDITERATOR_H
+
+#include <QtCore/QList>
+#include <QtCore/QVector>
+#include <QtCore/QSharedData>
+#include <QtCore/QString>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+template<typename T> class QVector;
+
+/* In this file we in some cases do not use QAbstractXmlForwardIterator's Ptr typedef.
+ * This is a compiler workaround for MS VS 6.0. */
+
+template<typename T>
+inline bool qIsForwardIteratorEnd(const T &unit)
+{
+ return !unit;
+}
+
+/**
+ * @short Helper class for StringSplitter
+ *
+ * Needed by the QAbstractXmlForwardIterator sub-class.
+ *
+ * @relates StringSplitter
+ */
+template<>
+inline bool qIsForwardIteratorEnd(const QString &unit)
+{
+ return unit.isNull();
+}
+
+template<typename T> class QAbstractXmlForwardIterator;
+
+class QAbstractXmlForwardIteratorPrivate;
+
+template<typename T>
+class QAbstractXmlForwardIterator : public QSharedData
+{
+public:
+ typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<T> > Ptr;
+ typedef QList<QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<T> > > List;
+ typedef QVector<QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<T> > > Vector;
+
+ inline QAbstractXmlForwardIterator() : d_ptr(0) {}
+ virtual ~QAbstractXmlForwardIterator() {}
+
+ virtual T next() = 0;
+ virtual T current() const = 0;
+
+ virtual qint64 position() const = 0;
+
+ virtual typename QAbstractXmlForwardIterator<T>::Ptr toReversed();
+ virtual QList<T> toList();
+ virtual typename QAbstractXmlForwardIterator<T>::Ptr copy() const;
+ virtual T last();
+ virtual bool isEmpty();
+ virtual qint64 count();
+ virtual qint64 sizeHint() const;
+
+private:
+ Q_DISABLE_COPY(QAbstractXmlForwardIterator<T>)
+
+ QAbstractXmlForwardIteratorPrivate *d_ptr; /* Currently not used. */
+};
+
+/* The namespace QPatternist and its members are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+namespace QPatternist
+{
+ class DeduplicateIterator;
+
+ template<typename InputType,
+ typename OutputType,
+ typename Derived,
+ typename ListType = QList<InputType> >
+ class ListIteratorPlatform : public QAbstractXmlForwardIterator<OutputType>
+ {
+ /* This declaration is a workaround for a set of GCC versions on OS X,
+ * amongst others powerpc-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1. In
+ * DeduplicateIterator, it fails to see the protected inheritance. */
+ friend class DeduplicateIterator;
+
+ public:
+ virtual OutputType next()
+ {
+ if(m_position == -1)
+ return OutputType();
+
+ if(m_position == m_list.count())
+ {
+ m_position = -1;
+ m_current = OutputType();
+ return OutputType();
+ }
+
+ m_current = static_cast<const Derived *>(this)->inputToOutputItem(m_list.at(m_position));
+ ++m_position;
+ return m_current;
+ }
+
+ virtual OutputType current() const
+ {
+ return m_current;
+ }
+
+ virtual qint64 position() const
+ {
+ return m_position;
+ }
+
+ virtual qint64 count()
+ {
+ return m_list.count();
+ }
+
+ virtual typename QAbstractXmlForwardIterator<OutputType>::Ptr copy() const
+ {
+ return QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<OutputType> >(new ListIteratorPlatform<InputType, OutputType, Derived, ListType>(m_list));
+ }
+
+ protected:
+ inline ListIteratorPlatform(const ListType &list) : m_list(list)
+ , m_position(0)
+ {
+ }
+
+ const ListType m_list;
+ qint64 m_position;
+ OutputType m_current;
+ };
+
+ template<typename T,
+ typename ListType = QList<T> >
+ class ListIterator : public ListIteratorPlatform<T, T, ListIterator<T, ListType>, ListType>
+ {
+ /*
+ * This declaration is needed for MSVC 2005, 14.00.50727.42 for 80x86.
+ */
+ friend class IteratorVector;
+
+ using ListIteratorPlatform<T, T, ListIterator<T, ListType>, ListType>::m_list;
+
+ static inline QVector<T> toVector(const QVector<T> &vector)
+ {
+ return vector;
+ }
+
+ static inline QVector<T> toVector(const QList<T> &list)
+ {
+ return list.toVector();
+ }
+
+ static inline QList<T> toList(const QVector<T> &vector)
+ {
+ return vector.toList();
+ }
+
+ static inline QList<T> toList(const QList<T> &list)
+ {
+ return list;
+ }
+
+ public:
+ inline ListIterator(const ListType &list) : ListIteratorPlatform<T, T, ListIterator<T, ListType>, ListType>(list)
+ {
+ }
+
+ virtual QList<T> toList()
+ {
+ return toList(m_list);
+ }
+
+ virtual QVector<T> toVector()
+ {
+ return toVector(m_list);
+ }
+
+ private:
+ inline const T &inputToOutputItem(const T &inputType) const
+ {
+ return inputType;
+ }
+ friend class ListIteratorPlatform<T, T, ListIterator<T, ListType>, ListType>;
+
+ // needed for MSVC 2005
+ friend class DeduplicateIterator;
+ };
+
+ template<typename T>
+ inline
+ typename QAbstractXmlForwardIterator<T>::Ptr
+ makeListIterator(const QList<T> &list)
+ {
+ return typename ListIterator<T>::Ptr(new ListIterator<T>(list));
+ }
+
+ template<typename T>
+ inline
+ typename QAbstractXmlForwardIterator<T>::Ptr
+ makeVectorIterator(const QVector<T> &vector)
+ {
+ return typename ListIterator<T, QVector<T> >::Ptr(new ListIterator<T, QVector<T> >(vector));
+ }
+}
+
+template<typename T>
+QList<T> QAbstractXmlForwardIterator<T>::toList()
+{
+ QList<T> result;
+ T item(next());
+
+ while(!qIsForwardIteratorEnd(item))
+ {
+ result.append(item);
+ item = next();
+ }
+
+ return result;
+}
+
+template<typename T>
+qint64 QAbstractXmlForwardIterator<T>::count()
+{
+ qint64 retval = 0;
+
+ while(!qIsForwardIteratorEnd(next()))
+ ++retval;
+
+ return retval;
+}
+
+template<typename T>
+typename QAbstractXmlForwardIterator<T>::Ptr QAbstractXmlForwardIterator<T>::toReversed()
+{
+ T item(next());
+ QList<T> result;
+
+ while(!qIsForwardIteratorEnd(item))
+ {
+ result.prepend(item);
+ item = next();
+ }
+
+ return QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<T> >(new QPatternist::ListIterator<T>(result));
+}
+
+template<typename T>
+T QAbstractXmlForwardIterator<T>::last()
+{
+ T item(next());
+
+ while(!qIsForwardIteratorEnd(item))
+ item = next();
+
+ return item;
+}
+
+template<typename T>
+typename QAbstractXmlForwardIterator<T>::Ptr QAbstractXmlForwardIterator<T>::copy() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "This function is internal, unsupported, and should never be called.");
+ return typename QAbstractXmlForwardIterator<T>::Ptr();
+}
+
+template<typename T>
+bool QAbstractXmlForwardIterator<T>::isEmpty()
+{
+ return qIsForwardIteratorEnd(next());
+}
+
+template<typename T>
+qint64 QAbstractXmlForwardIterator<T>::sizeHint() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This function is currently not expected to be used.");
+ return -1;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
new file mode 100644
index 0000000..c2000bb
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
@@ -0,0 +1,1683 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QVector>
+
+#include "qabstractxmlnodemodel_p.h"
+#include "qabstractxmlreceiver.h"
+#include "qcommonvalues_p.h"
+#include "qemptyiterator_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qitem_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qsequencemappingiterator_p.h"
+#include "qsingletoniterator_p.h"
+
+#include "qabstractxmlnodemodel.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndexIteratorPointer;
+
+/**
+ * @file
+ * @short Contains the implementation of QAbstractXmlNodeModel.
+ */
+
+bool QAbstractXmlNodeModel::isIgnorableInDeepEqual(const QXmlNodeModelIndex &n)
+{
+ Q_ASSERT(!n.isNull());
+ const QXmlNodeModelIndex::NodeKind nk = n.kind();
+ return nk == QXmlNodeModelIndex::ProcessingInstruction ||
+ nk == QXmlNodeModelIndex::Comment;
+}
+
+
+/*!
+ \class QAbstractXmlNodeModel
+ \brief The QAbstractXmlNodeModel class is an abstract base class for modeling non-XML data to look like XML for QXmlQuery.
+ \threadsafe
+ \since 4.4
+ \ingroup xml-tools
+
+ The QAbstractXmlNodeModel specifies the interface that a node model
+ must implement for that node model be accessible to the query engine
+ for processing XQuery queries. A node model represents data as a
+ structure that can be queried as if the data were XML.
+
+ The node model represented by a subclass of QAbstractXmlNodeModel is
+ meant to be accessed by the QtXmlPatterns query engine. If the API
+ seems a little strange in a few places, it is because the member
+ functions are called by the query engine as it evaluates an
+ XQuery. They aren't meant to be used programatically.
+
+ \section1 Usage
+
+ QAbstractXmlNodeModel bridges the gap between the arbitrary structure
+ of the non-XML data to be queried and the well-defined structure of
+ XML data understood by QXmlQuery.
+
+ Consider a chemistry application that reads the file \c
+ chemistryData, which contains non-XML data that represents a
+ chemical structure composed of molecules and atoms. The application
+ will query this chemistry data with an XQuery it reads from file \c
+ queryFile. We write a custom subclass of QAbstractXmlNodeModel (\c
+ ChemistryNodeModel) that reads \c chemistryData and builds a data
+ structure, perhaps composed of objects of our own classes \c
+ molecule and \c atom. Clearly, this data structure is not XML. Our
+ custom subclass will know how to traverse this non-XML structure and
+ present it through the \l
+ {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model interface}.
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 1
+
+ The application first creates an instance of QXmlQuery and calls \l
+ {QXmlQuery::setQuery()}{setQuery()} to read \c queryFile containing
+ the XQuery we want to run. Then it creates an instance of our custom
+ node model class, \c ChemistryNodeModel, which is a subclass of
+ QAbstractXmlNodeModel. Its constructor is called with the \l
+ {QXmlNamePool} {name pool} obtained from our QXmlQuery, and with the
+ \c chemistryFile containing the structure of molecules and atoms to
+ be queried. The \l {QXmlNamePool} {name pool} is required because
+ our custom node model has the member function \l
+ {QAbstractXmlNodeModel::name()} {name()}, which returns the \l
+ {QXmlName} {name} of any node in the model. The \l {QXmlQuery}
+ {query} and the custom node model must use the same name pool for
+ constructing these \l {QXmlName} {names}. The constructor would then
+ read \c chemistryFile and build the custom node model structure.
+
+ To connect the \c query to the custom node model, we must bind a
+ variable name used in the query to a node in the model. The variable
+ can then be used in the query as a starting node. First, an \l
+ {QXmlNodeModelIndex} {index} for the desired starting node is
+ retrieved by calling QAbstractXmlNodeModel::createIndex(). Then the
+ index is bound to a variable name, in this case \c queryRoot, by
+ passing the name and the index to QXmlQuery::bindVariable(). The
+ query can then use a variable reference \c $queryRoot to refer to
+ the starting node. Note that if the \l {QXmlQuery} {query} uses
+ multiple variable references, a call to QXmlQuery::bindVariable()
+ is required to bind each different variable name to a node in the
+ model.
+
+ The query is executed when the application calls one of the
+ QXmlQuery evaluation functions. The application uses
+ QXmlQuery::evaluateTo(QAbstractXmlReceiver *), because it then uses
+ a \l {QXmlSerializer} {serializer} to out the query result as XML to
+ \c stdout. We could have used QXmlQuery::evaluateTo(QXmlResultItems
+ *) to get a list of result items, or
+ QXmlQuery::evaluateTo(QStringList *) if the query evaluated to a
+ sequence of \c {xs:string} values.
+
+ During query execution, the engine iterates over the node model
+ using nextFromSimpleAxis() to get the \l {QXmlNodeModelIndex}
+ {index} of the next node to be visited. The engine can get the name
+ of a node by calling name() with the node's \l {QXmlNodeModelIndex}
+ {index}. stringValue(), baseUri(), documentUri() and kind() are also
+ called as needed with a node \l {QXmlNodeModelIndex} {index}.
+
+ The example demonstrates the standard pattern for using a subclass
+ of QAbstractXmlNodeModel in combination with QXmlQuery to perform
+ an XQuery.
+
+ \list 1
+
+ \o Instantiate QXmlQuery and give it the XQuery to be run;
+
+ \o Instantiate a subclass of QAbstractXmlNodeModel or
+ QSimpleXmlNodeModel;
+
+ \o Retrieve a QXmlNodeModelIndex for the node in the model where
+ the QXmlQuery should start the query;
+
+ \o Use QXmlQuery::bindVariable() to bind the QXmlNodeModelIndex
+ to \c {$variable name};
+
+ \o Call one of the QXmlQuery evaluation functions to run the
+ query.
+
+ \endlist
+
+ \section1 Subclassing
+
+ Because the \l {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model
+ interface} presented by QAbstractXmlNodeModel allows QXmlQuery to
+ operate on non-XML data as if it were XML, implementing subclasses
+ of QAbstractXmlNodeModel can involve a significant amount of
+ work. The QSimpleXmlNodeModel class is provided to simplify the
+ implementation for many common use cases.
+
+ \section1 Thread Safety
+
+ Because the node model can be accessed concurrently by threads in
+ the QtXmlPatterns module, subclasses of QAbstractXmlNodeModel must
+ be written to be \l{Reentrancy and Thread-Safety}{thread-safe}.
+ Classes that simplify implementing thread-safety include QReadLocker
+ and QWriteLocker.
+
+ See the example \l{File System Example} for a demonstration.
+ */
+
+/*!
+ \enum QXmlNodeModelIndex::Constants
+
+ \value ForwardAxis All forward axes include this flag.
+ \value ReverseAxis All reverse axes include this flag.
+ */
+
+/*!
+ \enum QXmlNodeModelIndex::DocumentOrder
+
+ Identifies the specific node comparison operator that should be
+ used.
+
+ \value Precedes Signifies the \c \<\< operator. Test whether the
+ first operand precedes the second in the document.
+
+ \value Follows Signifies the \c \>\> operator. Test whether the
+ first operand follows the second in the document.
+
+ \value Is Signifies the \c is operator. Test whether two nodes have
+ the same node identity.
+ */
+
+/*!
+ \enum QAbstractXmlNodeModel::SimpleAxis
+
+ Four axes that each contain one node only.
+
+ \value Parent The parent of the context node
+ \value FirstChild The first child of the context node
+ \value PreviousSibling The previous child of the context node
+ \value NextSibling The next child of the context node
+*/
+
+/*!
+ \enum QXmlNodeModelIndex::Axis
+ \internal
+
+ Identify the axes emanating from a node.
+
+ The axes AxisChild, AxisDescendant, AxisAttribute, AxisSelf,
+ AxisDescendantOrSelf, AxisFollowingSibling, and AxisFollowing are
+ forward axes.
+
+ The axes AxisParent, AxisAncestor, AxisPrecedingSibling,
+ AxisPreceding and AxisAncestorOrSelf are reverse axes.
+
+ \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
+
+ \value AxisChild The \c child axis.
+
+ \value AxisDescendant The \c descendant axis.
+
+ \value AxisAttribute The \c attribute axis. Note: There
+ is a node kind named \c{Attribute}.
+
+ \value AxisSelf The \c self axis.
+
+ \value AxisDescendantOrSelf The \c descendant-or-self axis.
+
+ \value AxisFollowingSibling The \c following-sibling axis.
+
+ \value AxisNamespace The \c namespace axis. Note: Does
+ not exist in XQuery; deprecated in
+ XPath 2.0 (optionally supported);
+ mandatory in XPath 1.0.
+
+ \value AxisFollowing The \c following axis.
+
+ \value AxisParent The \c parent axis.
+
+ \value AxisAncestor The \c ancestor axis.
+
+ \value AxisPrecedingSibling The \c preceding-sibling axis.
+
+ \value AxisPreceding The \c preceding axis.
+
+ \value AxisAncestorOrSelf The \c ancestor-or-self axis.
+*/
+
+using namespace QPatternist;
+
+/*!
+ Default constructor.
+ */
+QAbstractXmlNodeModel::QAbstractXmlNodeModel() : d_ptr(0)
+{
+}
+
+/*!
+ \internal
+
+ Takes the d-pointer.
+
+ */
+QAbstractXmlNodeModel::QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d) : d_ptr(d)
+{
+}
+
+/*!
+ Destructor.
+ */
+QAbstractXmlNodeModel::~QAbstractXmlNodeModel()
+{
+}
+
+/*!
+ \typedef QAbstractXmlNodeModel::List
+
+ A \l{QList}{list} of \l{QExplicitlySharedDataPointer} {smart
+ pointers} to instances of QAbstractXmlNodeModel.
+
+ \sa QExplicitlySharedDataPointer
+ */
+
+/*!
+ \typedef QAbstractXmlNodeModel::Ptr
+
+ A \l {QExplicitlySharedDataPointer} {smart pointer} to an
+ instance of QAbstractXmlNodeModel.
+
+ \sa QExplicitlySharedDataPointer
+ */
+
+/*!
+ \fn QUrl QAbstractXmlNodeModel::baseUri(const QXmlNodeModelIndex &n) const
+
+ Returns the base URI for the node whose index is \a n. The caller
+ guarantees that \a n is not \c null and that it belongs to a node
+ in this node model.
+
+ The base URI of a node can be extracted using the \c fn:base-uri()
+ function. The base URI is typically used for resolving relative URIs
+ that appear in the node or its children. It is conformant to just
+ return the document URI, although that might not properly reflect
+ the underlying data.
+
+ This function maps to the \c dm:base-uri accessor, which returns
+ a base URI according to the following:
+
+ \list
+
+ \o For document nodes, the base URI and the document URI are the same.
+
+ \o For elements, the base URI is the URI appearing in the element's
+ \c xml:base attribute, if present, or it is resolved to the
+ parent element's base URI.
+
+ \o Namespace nodes have no base URI.
+
+ \o The base URI for a processing instruction, comment, attribute,
+ or text node is the base URI of the node's parent element.
+
+ \endlist
+
+ The implementation guarantees to return a valid QUrl, or a default
+ constructed QUrl. If a node has no base URI, as in the case where a
+ comment has no parent, a default constructed QUrl is returned.
+
+ \sa {http://www.w3.org/TR/xpath-datamodel/#dm-base-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.2 base-uri Accessor}
+ */
+
+/*!
+ \fn QUrl QAbstractXmlNodeModel::documentUri(const QXmlNodeModelIndex &n) const
+
+ Returns the document URI of \a n. The document URI identifies the
+ resource which is the document. For example, the document could be a
+ regular file, e.g., \c{file:/}, or it could be the \c{http://} URL of
+ the location of a file. The document URI is used for resolving URIs
+ and to simply know where the document is.
+
+ If the node model maps to a URI in a natural way, return that URI.
+ Otherwise, return the company or product URI. The document URI can
+ be any URI as long as its valid and absolute.
+
+ The caller guarantees that \a n is not \c null and that it belongs
+ to this QAbstractXmlNodeModel.
+
+ This function maps to the \c dm:document-uri accessor, which
+ returns a document URI according to the following:
+
+ \list
+
+ \o If \a n is a document node, return an absolute QUrl containing
+ the document URI, or a default constructed QUrl. The latter
+ signals that no document URI is available for the document node.
+
+ \o For all other nodes, return a default constructed QUrl.
+
+ \endlist
+
+ \sa {http://www.w3.org/TR/xpath-datamodel/#dm-document-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.4 document-uri Accessor}
+ \sa QUrl::isValid(), QUrl::isRelative()
+ */
+
+/*
+### Qt 5:
+
+Add the function:
+
+ virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &nodeIndex) const = 0;
+
+Such that the data model can communicate back source locations.
+ */
+
+/*!
+ \fn QXmlNodeModelIndex::NodeKind QAbstractXmlNodeModel::kind(const QXmlNodeModelIndex &ni) const
+
+ Returns a value indicating the kind of node identified by \a ni.
+ The caller guarantees that \a ni is not null and that it identifies
+ a node in this node model. This function maps to the \c
+ dm:node-kind() accessor.
+
+ \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-kind}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.10 node-kind Accessor}
+ */
+
+/*!
+ \fn QXmlNodeModelIndex::DocumentOrder QAbstractXmlNodeModel::compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const
+
+ This function returns the relative document order for the
+ nodes indexed by \a ni1 and \a ni2. It is used for the \c Is
+ operator and for sorting nodes in document order.
+
+ The caller guarantees that \a ni1 and \a ni2 are not \c null and
+ that both identify nodes in this node model.
+
+ If \a ni1 is identical to \a ni2, QXmlNodeModelIndex::Is is returned.
+ If \a ni1 precedes \a ni2 in document order, QXmlNodeModelIndex::Precedes
+ is returned. If \a ni1 follows \a ni2 in document order,
+ QXmlNodeModelIndex::Follows is returned.
+
+ \sa {http://www.w3.org/TR/xpath-datamodel/#document-order}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 2.4 Document Order}
+ */
+
+/*!
+ \fn QXmlNodeModelIndex QAbstractXmlNodeModel::root(const QXmlNodeModelIndex &n) const
+
+ Returns the root node of the tree that contains the node whose index
+ is \a n. The caller guarantees that \a n is not \c null and that it
+ identifies a node in this node model.
+
+ If \a n identifies a node that is a direct child of the root,
+ parent() would return the same QXmlNodeModelIndex returned by
+ this function.
+ */
+
+namespace QPatternist
+{
+ class MergeIterator
+ {
+ public:
+ inline MergeIterator()
+ {
+ }
+
+ inline
+ QXmlNodeModelIndexIteratorPointer
+ mapToSequence(const QXmlNodeModelIndexIteratorPointer &it,
+ const DynamicContext::Ptr &) const
+ {
+ return it;
+ }
+
+ private:
+ Q_DISABLE_COPY(MergeIterator)
+ };
+
+ static const MergeIterator mergeIterator;
+
+ /**
+ * One might wonder, why not use makeVectorIterator() directly on a QVector
+ * with iterators?
+ *
+ * A problem emerges QAbstractXmlForwardIterator::copy(). All "meta
+ * iterators" that contain other iterators and so forth, propagate the
+ * copy() call such that all involved iterators are copied. However, if we
+ * have a ListIterator of iterators it isn't aware of that it contains
+ * iterators. Hence, we have this class which is specialized(not in the
+ * template sense) on iterators, and hence copies them appropriately.
+ */
+ class IteratorVector : public ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >
+ {
+ typedef QVector<QXmlNodeModelIndexIteratorPointer> ItVector;
+ public:
+ typedef QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr Ptr;
+
+ IteratorVector(const ItVector &in) : ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >(in)
+ {
+ }
+
+ virtual QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr copy() const
+ {
+ ItVector result;
+
+ for(int i = 0; i < m_list.count(); ++i)
+ result.append(m_list.at(i)->copy());
+
+ return Ptr(new IteratorVector(result));
+ }
+ };
+}
+
+/*!
+ \internal
+ This function is not a private member of QAbstractXmlNodeModel
+ because it would be messy to forward declare the required types.
+*/
+static inline QXmlNodeModelIndexIteratorPointer mergeIterators(const QXmlNodeModelIndex &node,
+ const QXmlNodeModelIndexIteratorPointer &it2)
+{
+ QVector<QXmlNodeModelIndexIteratorPointer> iterators;
+ iterators.append(makeSingletonIterator(node));
+ iterators.append(it2);
+
+ return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
+ IteratorVector::Ptr(new IteratorVector(iterators)),
+ DynamicContext::Ptr());
+}
+
+inline QAbstractXmlForwardIterator<QXmlNodeModelIndex>::Ptr
+QAbstractXmlNodeModel::mapToSequence(const QXmlNodeModelIndex &ni,
+ const DynamicContext::Ptr &) const
+{
+ Q_ASSERT(!ni.isNull());
+ /* Since we pass in this here, mapToSequence is used recursively. */
+ return mergeIterators(ni, makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
+ ni.iterate(QXmlNodeModelIndex::AxisChild),
+ DynamicContext::Ptr()));
+}
+
+/*!
+ \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::attributes(const QXmlNodeModelIndex &element) const
+
+ Returns the attributes of \a element. The caller guarantees
+ that \a element is an element in this node model.
+ */
+
+/*!
+ \internal
+
+ Performs navigation, starting from \a ni, by returning an
+ QAbstractXmlForwardIterator that returns nodes the \a axis emanating
+ from \a ni.
+
+ The implementation returns the nodes on the \a axis, without
+ duplicates and in \a axis order. This means that if \a axis is a
+ reverse axis, which is the case for the \c parent, \c ancestor, \c
+ ancestor-or-self, \c preceding, and \c preceding-sibling, the nodes
+ are delivered in reverse document order. Otherwise the nodes are
+ delivered in document order.
+
+ The implementor guarantees that the nodes delivered for the axes are
+ consistent with the XPath Data Model. This just implies common
+ sense, e.g., The child axis for a comment node can't contain any
+ children; a document node can't be a child of an element, etc.
+ Attributes aren't considered children of an element, but are only
+ available on AxisAttribute.
+
+ The value past in \a axis is not guaranteed based on what is used in
+ a query. QtXmlPatterns may call this function arbitrarily with any
+ value for \a axis. This is because QtXmlPatterns may rewrite queries
+ to be more efficient, using axes in different ways from the original
+ query.
+
+ QAbstractXmlNodeModel::Axis has a good overview of the axes and what
+ they select.
+
+ The caller guarantees that \a ni is not \c null and that it belongs
+ to this QAbstractXmlNodeModel instance.
+
+ Implementing iterate() can involve significant work, since it
+ requires different iterators for all the axes used. In the worst
+ case, it could require writing as many QAbstractXmlForwardIterator
+ subclasses as there are axes, but the number can often be reduced
+ with clever use of lists and template classes. It is better to use
+ or subclass QSimpleXmlNodeModel, which makes it easier to write the
+ node navigation code without loss of efficiency or flexibility.
+
+ \sa QSimpleXmlNodeModel
+ \sa QXmlNodeModelIndex::Axis
+ \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
+ \sa {http://www.w3.org/TR/xpath-datamodel/}{W3CXQuery 1.0 and XPath 2.0 Data Model (XDM)}
+ */
+QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> >
+QAbstractXmlNodeModel::iterate(const QXmlNodeModelIndex &ni,
+ QXmlNodeModelIndex::Axis axis) const
+{
+ /* Returns iterators that track state and calls nextFromSimpleAxis()
+ * iteratively. Typically, when sub-classing QSimpleXmlNodeModel,
+ * you don't reimplement this function, but instead implement
+ * nextFromSimpleAxis(). */
+
+ switch(axis)
+ {
+ case QXmlNodeModelIndex::AxisSelf:
+ return makeSingletonIterator(ni);
+ case QXmlNodeModelIndex::AxisParent:
+ {
+ if(kind(ni) == QXmlNodeModelIndex::Document)
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ else
+ return makeSingletonIterator(nextFromSimpleAxis(Parent, ni));
+ }
+ case QXmlNodeModelIndex::AxisNamespace:
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+ case QXmlNodeModelIndex::AxisAncestor:
+ {
+ QList<QXmlNodeModelIndex> ancestors;
+ QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
+
+ while(!ancestor.isNull())
+ {
+ ancestors.append(ancestor);
+ ancestor = nextFromSimpleAxis(Parent, ancestor);
+ }
+
+ return makeListIterator(ancestors);
+ }
+ case QXmlNodeModelIndex::AxisAncestorOrSelf:
+ {
+ QList<QXmlNodeModelIndex> ancestors;
+ ancestors.append(ni);
+ QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);
+
+ while(!ancestor.isNull())
+ {
+ ancestors.append(ancestor);
+ ancestor = nextFromSimpleAxis(Parent, ancestor);
+ }
+
+ return makeListIterator(ancestors);
+ }
+ case QXmlNodeModelIndex::AxisPrecedingSibling:
+ {
+ QList<QXmlNodeModelIndex> preceding;
+ QXmlNodeModelIndex sibling = nextFromSimpleAxis(PreviousSibling, ni);
+
+ while(!sibling.isNull())
+ {
+ preceding.append(sibling);
+ sibling = nextFromSimpleAxis(PreviousSibling, sibling);
+ }
+
+ return makeListIterator(preceding);
+ }
+ case QXmlNodeModelIndex::AxisFollowingSibling:
+ {
+ QList<QXmlNodeModelIndex> preceding;
+ QXmlNodeModelIndex sibling = nextFromSimpleAxis(NextSibling, ni);
+
+ while(!sibling.isNull())
+ {
+ preceding.append(sibling);
+ sibling = nextFromSimpleAxis(NextSibling, sibling);
+ }
+
+ return makeListIterator(preceding);
+ }
+ case QXmlNodeModelIndex::AxisChildOrTop:
+ {
+ if(nextFromSimpleAxis(Parent, ni).isNull())
+ {
+ switch(kind(ni))
+ {
+ case QXmlNodeModelIndex::Comment:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Element:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Text:
+ return makeSingletonIterator(ni);
+ case QXmlNodeModelIndex::Attribute:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Document:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Namespace:
+ /* Do nothing. */;
+ }
+ }
+
+ /* Else, fallthrough to AxisChild. */
+ }
+ case QXmlNodeModelIndex::AxisChild:
+ {
+ QList<QXmlNodeModelIndex> children;
+ QXmlNodeModelIndex child = nextFromSimpleAxis(FirstChild, ni);
+
+ while(!child.isNull())
+ {
+ children.append(child);
+ child = nextFromSimpleAxis(NextSibling, child);
+ }
+
+ return makeListIterator(children);
+ }
+ case QXmlNodeModelIndex::AxisDescendant:
+ {
+ return makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
+ ni.iterate(QXmlNodeModelIndex::AxisChild),
+ DynamicContext::Ptr());
+ }
+ case QXmlNodeModelIndex::AxisAttributeOrTop:
+ {
+ if(kind(ni) == QXmlNodeModelIndex::Attribute && nextFromSimpleAxis(Parent, ni).isNull())
+ return makeSingletonIterator(ni);
+
+ /* Else, fallthrough to AxisAttribute. */
+ }
+ case QXmlNodeModelIndex::AxisAttribute:
+ return makeVectorIterator(attributes(ni));
+ case QXmlNodeModelIndex::AxisDescendantOrSelf:
+ return mergeIterators(ni, iterate(ni, QXmlNodeModelIndex::AxisDescendant));
+ case QXmlNodeModelIndex::AxisFollowing:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::AxisPreceding:
+ {
+ /* We walk up along the ancestors, and for each parent, we grab its preceding/following
+ * siblings, and evaluate the descendant axis. The descendant axes gets added
+ * to a list and we then merge those iterators. */
+ QVector<QXmlNodeModelIndexIteratorPointer> descendantIterators;
+
+ QXmlNodeModelIndex current(ni);
+ while(!current.isNull())
+ {
+ QXmlNodeModelIndex candidate(nextFromSimpleAxis(axis == QXmlNodeModelIndex::AxisPreceding ? PreviousSibling : NextSibling, current));
+ if(candidate.isNull())
+ {
+ /* current is an ancestor. We don't want it, so next iteration we
+ * will grab its preceding sibling. */
+ current = nextFromSimpleAxis(Parent, current);
+ }
+ else
+ {
+ current = candidate;
+ descendantIterators.append(iterate(current, QXmlNodeModelIndex::AxisDescendantOrSelf)->toReversed());
+ }
+ }
+
+ return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
+ IteratorVector::Ptr(new IteratorVector(descendantIterators)),
+ DynamicContext::Ptr());
+ }
+ }
+
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown axis, internal error.");
+ return makeEmptyIterator<QXmlNodeModelIndex>();
+}
+
+/*!
+ \fn QXmlNodeModelIndex QAbstractXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
+
+ When QtXmlPatterns evaluate path expressions, it emulate them through a
+ combination of calls with QSimpleXmlNodeModel::SimpleAxis values. Therefore,
+ the implementation of this function must return the node, if any, that
+ appears on the \a axis emanating from the \a origin.
+
+ If no such node is available, a default constructed
+ QXmlNodeModelIndex is returned.
+
+ QSimpleXmlNodeModel eliminates the need to handle redundant corner
+ cases by guaranteeing that it will never ask for:
+
+ \list
+ \o Children or siblings for attributes.
+ \o Children for comments, processing instructions, and text nodes.
+ \o Siblings or parents for document nodes.
+ \endlist
+
+ A typical implementation performs a \c switch on the value of \a
+ axis:
+
+ \code
+ QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
+ {
+ // Convert the QXmlNodeModelIndex to a value that is specific to what we represent.
+ const MyValue value = toMyValue(ni);
+
+ switch(axis)
+ {
+ case Parent:
+ return toNodeIndex(value.parent());
+ case FirstChild:
+ case PreviousSibling:
+ case NextSibling:
+ // and so on
+ }
+ }
+ \endcode
+
+ */
+
+/*!
+ \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data) const
+
+ Creates a node index with \a data as its internal data. \a data is
+ not constrained.
+ */
+
+/*!
+ \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(void *pointer, qint64 additionalData) const
+
+ Creates a node index with \a pointer and \a additionalData as
+ its internal data.
+
+ What \a pointer and \a additionalData is, is not constrained.
+ */
+
+/*!
+ \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data, qint64 additionalData) const;
+ \overload
+
+ Creates a QXmlNodeModelIndex containing \a data and \a
+ additionalData.
+ */
+
+/*!
+ \fn QXmlName QAbstractXmlNodeModel::name(const QXmlNodeModelIndex &ni) const
+
+ Returns the name of \a ni. The caller guarantees that \a ni is not
+ \c null and that it belongs to this QAbstractXmlNodeModel.
+
+ If a node does not have a name, e.g., comment nodes, a null QXmlName
+ is returned. QXmlNames must be created with the instance of
+ QXmlQuery that is being used for evaluating queries using this
+ QAbstractXmlNodeModel.
+
+ This function maps to the \c dm:node-name() accessor.
+
+ If \a ni is a processing instruction, a QXmlName is returned with
+ the local name as the target name and the namespace URI and prefix
+ both empty.
+
+ \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-name}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.11 node-name Accessor}
+ \sa QXmlName
+ */
+
+/*!
+ \fn QVector<QXmlName> QAbstractXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &n) const
+
+ Returns the in-scope namespaces of \a n. The caller guarantees that
+ \a n is not \c null and that it belongs to this QAbstractXmlNodeModel.
+
+ This function corresponds to the \c dm:namespace-nodes accessor.
+
+ The returned vector of namespace declarations includes namespaces
+ of the ancestors of \a n.
+
+ The caller guarantees that \a n is an Element that belongs to this
+ QAbstractXmlNodeModel.
+ */
+
+/*!
+ \internal
+ Sends the namespaces declared on \a n to \a receiver.
+
+ As a consequence, no namespaces are sent unless this node is an
+ element and has namespaces declared.
+
+ The caller guarantees that \a n is not \c null and that it belongs
+ to this QAbstractXmlNodeModel instance.
+
+ Note that it is not the namespaces that are in scope on \a n, but
+ only the namespaces that are specifically declared on \a n.
+
+ \a receiver is the receiver that this node is supposed to send its
+ namespaces to. This is guaranteed by the caller to be a valid
+ pointer. \a n is the index of the node whose namespaces are to
+ be sent.
+ */
+void QAbstractXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &n,
+ QAbstractXmlReceiver *const receiver) const
+{
+ Q_ASSERT(receiver);
+ const QVector<QXmlName> nss(namespaceBindings(n));
+
+ /* This is by far the most common case. */
+ if(nss.isEmpty())
+ return;
+
+ const int len = nss.size();
+ for(int i = 0; i < len; ++i)
+ receiver->namespaceBinding(nss.at(i));
+}
+
+/*!
+ \fn QString QAbstractXmlNodeModel::stringValue(const QXmlNodeModelIndex &n) const
+
+ Returns the string value for node \a n.
+
+ The caller guarantees that \a n is not \c null and that it belong to
+ this QAbstractXmlNodeModel instance.
+
+ This function maps to the \c dm:string-value() accessor, which the
+ specification completely specifies. Here's a summary:
+
+ \list
+
+ \o For processing instructions, the string value is the data
+ section(excluding any whitespace appearing between the name and the
+ data).
+
+ \o For text nodes, the string value equals the text node.
+
+ \o For comments, the content of the comment
+
+ \o For elements, the concatenation of all text nodes that are
+ descendants. Note, this is not only the children, but the
+ childrens' childrens' text nodes, and so forth.
+
+ \o For document nodes, the concatenation of all text nodes in the
+ document.
+
+ \endlist
+
+ \sa {http://www.w3.org/TR/xpath-datamodel/#dm-string-value}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.13 string-value Accessor}
+ */
+
+/*!
+ \fn QVariant QAbstractXmlNodeModel::typedValue(const QXmlNodeModelIndex &node) const
+
+ Returns the typed value for node \a node.
+
+ The typed value is an atomic value, which an element or attribute
+ contains.
+
+ The caller guarantees that \a node is either an element or an
+ attribute. The implementor guarantees that the returned QVariant has
+ a value which is supported in XQuery. It cannot be an arbitrary
+ QVariant value. The implementor also guarantees that stringValue()
+ returns a lexical representation of typedValue()(this is guaranteed
+ by QSimpleXmlNodeModel::stringValue()).
+
+ If the return QVariant is a default constructed variant, it signals
+ that \a node has no typed value.
+*/
+
+/*!
+ \internal
+ */
+QPatternist::ItemIteratorPtr QAbstractXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &ni) const
+{
+ const QVariant &candidate = typedValue(ni);
+ if(candidate.isNull())
+ return QPatternist::CommonValues::emptyIterator;
+ else
+ return makeSingletonIterator(AtomicValue::toXDM(candidate));
+}
+
+/*!
+ \internal
+ */
+QPatternist::ItemTypePtr QAbstractXmlNodeModel::type(const QXmlNodeModelIndex &) const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "This function is internal and must not be called.");
+ return QPatternist::ItemTypePtr();
+}
+
+/*!
+ \internal
+
+ Returns the namespace URI on \a ni that corresponds to \a prefix.
+
+ If \a prefix is StandardPrefixes::empty, the namespace URI for the
+ default namespace is returned.
+
+ The default implementation use namespaceBindings(), in a straight
+ forward manner.
+
+ If no namespace exists for \a prefix, NamespaceResolver::NoBinding
+ is returned.
+
+ The caller guarantees to only call this function for element nodes.
+ */
+QXmlName::NamespaceCode QAbstractXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &ni,
+ const QXmlName::PrefixCode prefix) const
+{
+ Q_ASSERT(kind(ni) == QXmlNodeModelIndex::Element);
+
+ const QVector<QXmlName> nbs(namespaceBindings(ni));
+ const int len = nbs.size();
+
+ for(int i = 0; i < len; ++i)
+ {
+ if(nbs.at(i).prefix() == prefix)
+ return nbs.at(i).namespaceURI();
+ }
+
+ return NamespaceResolver::NoBinding;
+}
+
+
+/*!
+ \internal
+
+ Determines whether \a ni1 is deep equal to \a ni2.
+
+ isDeepEqual() is defined as evaluating the expression \c
+ fn:deep-equal($n1, $n2) where \c $n1 is \a ni1 and \c $n1 is \a
+ ni2. This function is associative, meaning the same value is
+ returned regardless of if isDeepEqual() is invoked with \a ni1 as
+ first argument or second. It is guaranteed that \a ni1 and \a ni2
+ are nodes, as opposed to the definition of \c fn:deep-equal().
+
+ Returns true if \a ni1 is deep-equal to \a ni2, otherwise false
+
+ \sa {"http://www.w3.org/TR/xpath-functions/#func-deep-equal"}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.3.1 fn:deep-equal}
+ */
+bool QAbstractXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &n1,
+ const QXmlNodeModelIndex &n2) const
+{
+ Q_ASSERT(!n1.isNull());
+ Q_ASSERT(!n2.isNull());
+
+ const QXmlNodeModelIndex::NodeKind nk = n1.kind();
+
+ if(nk != n2.kind())
+ return false;
+
+ if(n1.name() != n2.name())
+ return false;
+
+ switch(nk)
+ {
+ case QXmlNodeModelIndex::Element:
+ {
+ QXmlNodeModelIndexIteratorPointer atts1(n1.iterate(QXmlNodeModelIndex::AxisAttribute));
+ QXmlNodeModelIndex node(atts1->next());
+
+ const QXmlNodeModelIndex::List atts2(n2.iterate(QXmlNodeModelIndex::AxisAttribute)->toList());
+ const QXmlNodeModelIndex::List::const_iterator end(atts2.constEnd());
+
+ while(!node.isNull())
+ {
+ bool equal = false;
+ for(QXmlNodeModelIndex::List::const_iterator it = atts2.constBegin(); it != end; ++it)
+ {
+ if(isDeepEqual(node, (*it)))
+ equal = true;
+ }
+
+ if(!equal)
+ return false;
+
+ node = atts1->next();
+ }
+
+ /* Fallthrough, so we check the children. */
+ }
+ case QXmlNodeModelIndex::Document:
+ {
+ QXmlNodeModelIndexIteratorPointer itn1(n1.iterate(QXmlNodeModelIndex::AxisChild));
+ QXmlNodeModelIndexIteratorPointer itn2(n2.iterate(QXmlNodeModelIndex::AxisChild));
+
+ while(true)
+ {
+ QXmlNodeModelIndex no1(itn1->next());
+ QXmlNodeModelIndex no2(itn2->next());
+
+ while(!no1.isNull() && isIgnorableInDeepEqual(no1))
+ no1 = itn1->next();
+
+ while(!no2.isNull() && isIgnorableInDeepEqual(no2))
+ no2 = itn2->next();
+
+ if(!no1.isNull() && !no2.isNull())
+ {
+ if(!isDeepEqual(no1, no2))
+ return false;
+ }
+ else
+ return no1.isNull() && no2.isNull();
+ }
+
+ return true;
+ }
+ case QXmlNodeModelIndex::Attribute:
+ /* Fallthrough */
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Text:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Comment:
+ return n1.stringValue() == n2.stringValue();
+ case QXmlNodeModelIndex::Namespace:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
+ return false;
+ }
+ }
+
+ return false;
+}
+
+/*!
+ \class QXmlItem
+ \reentrant
+ \since 4.4
+ \brief The QXmlItem class contains either an XML node or an atomic value.
+ \ingroup xml-tools
+
+ In XQuery, all expressions evaluate to a sequence of items, where
+ each item is either an XML node or an atomic value. The query in the
+ following snippet evaluates to sequence of five items.
+
+ \quotefile doc/src/snippets/patternist/items.xq
+
+ The five items are: An element, an atomic value (binary data encoded
+ in base64), a date, a float, and an attribute.
+
+ QXmlItem is the class that represents these XQuery items in the
+ QtXmlPatterns API. A non-null instance of QXmlItem is either a node
+ or an atomic value. Calling isNode() or isAtomicValue() tells you
+ which it is. Atomic values are represented elsewhere in the Qt API
+ as instances of QVariant, and an instance of QXmlItem that
+ represents an atomic value can be converted to a QVariant by calling
+ toAtomicValue(). A QXmlItem that wraps a node is represented
+ elsewhere as an instance of QXmlNodeModelIndex. A node QXmlItem can
+ be converted to a QXmlNodeModelIndex by calling toNodeModelIndex().
+
+ A default constructed QXmlItem instance is neither a node nor an
+ atomic value. It is considered null, in which case isNull() returns
+ true.
+
+ An instance of QXmlItem will be left dangling if the
+ \l{QAbstractXmlNodeModel} {XML node model} it
+ refers to is deleted, if it is a QXmlNodeModelIndex.
+ */
+
+/*!
+ \typedef QXmlItem::Iterator
+ A QAbstractXmlForwardIterator over QXmlItem.
+ */
+
+/*!
+ Constructs a null QXmlItem that is neither a node nor an atomic
+ value. isNull() returns true for a default constructed instance.
+ */
+QXmlItem::QXmlItem()
+{
+ m_node.model = 0;
+ m_node.data = 0;
+ m_node.additionalData = 0;
+}
+
+bool QXmlItem::internalIsAtomicValue() const
+{
+ return m_node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
+}
+
+/*!
+ The copy constructor constructs a copy of \a other.
+ */
+QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
+{
+ if(internalIsAtomicValue())
+ m_atomicValue->ref.ref();
+}
+
+/*!
+ Constructs an atomic value QXmlItem with \a atomicValue.
+
+ \sa isAtomicValue()
+ */
+QXmlItem::QXmlItem(const QVariant &atomicValue)
+{
+ if(atomicValue.isNull())
+ {
+ /* Then we behave just like the default constructor. */
+ m_node.model = 0;
+ m_node.data = 0;
+ m_node.additionalData = 0;
+ return;
+ }
+
+ /*
+ We can't assign directly to m_atomicValue, because the
+ temporary will self-destruct before we've ref'd it.
+ */
+ const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue));
+
+ if(temp)
+ {
+ temp.asAtomicValue()->ref.ref();
+ m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
+ m_atomicValue = temp.asAtomicValue();
+ }
+ else
+ {
+ m_atomicValue = 0;
+ m_node.model = 0;
+ }
+
+ m_node.additionalData = 0;
+}
+
+/*!
+ Constructs a node QXmlItem that is a copy of \a node.
+
+ \sa isNode()
+ */
+QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage)
+{
+}
+
+
+/*!
+ Destructor.
+ */
+QXmlItem::~QXmlItem()
+{
+ if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
+ delete m_atomicValue;
+}
+
+bool QPatternist::NodeIndexStorage::operator!=(const NodeIndexStorage &other) const
+{
+ return data != other.data
+ || additionalData != other.additionalData
+ || model != other.model;
+}
+
+/*!
+ Assigns \a other to \c this.
+ */
+QXmlItem &QXmlItem::operator=(const QXmlItem &other)
+{
+ if(m_node != other.m_node)
+ {
+ if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
+ delete m_atomicValue;
+
+ m_node = other.m_node;
+
+ if(internalIsAtomicValue())
+ m_atomicValue->ref.ref();
+ }
+
+ return *this;
+}
+
+/*!
+ Returns true if this item is a Node. Returns false if it
+ is an atomic value or null.
+
+ \sa isNull(), isAtomicValue()
+ */
+bool QXmlItem::isNode() const
+{
+ return QPatternist::Item::fromPublic(*this).isNode();
+}
+
+/*!
+ Returns true if this item is an atomic value. Returns false
+ if it is a node or null.
+
+ \sa isNull(), isNode()
+ */
+bool QXmlItem::isAtomicValue() const
+{
+ return internalIsAtomicValue();
+}
+
+/*!
+ If this QXmlItem represents an atomic value, it is converted
+ to an appropriate QVariant and returned. If this QXmlItem is
+ not an atomic value, the return value is a default constructed
+ QVariant. You can call isAtomicValue() to test whether the
+ item is an atomic value.
+
+ \sa isAtomicValue()
+ */
+QVariant QXmlItem::toAtomicValue() const
+{
+ if(isAtomicValue())
+ return QPatternist::AtomicValue::toQt(m_atomicValue);
+ else
+ return QVariant();
+}
+
+/*!
+ If this QXmlItem represents a node, it returns the item as a
+ QXmlNodeModelIndex. If this QXmlItem is not a node, the return
+ value is undefined. You can call isNode() to test whether the
+ item is a node.
+
+ \sa isNode()
+ */
+QXmlNodeModelIndex QXmlItem::toNodeModelIndex() const
+{
+ if(isNode())
+ return reinterpret_cast<const QXmlNodeModelIndex &>(m_node);
+ else
+ return QXmlNodeModelIndex();
+}
+
+/*!
+ Returns true if this QXmlItem is neither a node nor an
+ atomic value. Default constructed instances of QXmlItem
+ are null.
+ */
+bool QXmlItem::isNull() const
+{
+ return !m_node.model;
+}
+
+/*!
+ \class QXmlNodeModelIndex
+ \brief The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeModel.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ QXmlNodeModelIndex is an index into an \l{QAbstractXmlNodeModel}
+ {XML node model}. It contains:
+
+ \list
+ \o A pointer to an \l{QAbstractXmlNodeModel} {XML node model},
+ which is returned by model(), and
+ \o Some data, which is returned by data(), internalPointer(),
+ and additionalData().
+ \endlist
+
+ Because QXmlNodeModelIndex is intentionally a simple class, it
+ doesn't have member functions for accessing the properties of
+ nodes. For example, it doesn't have functions for getting a
+ node's name or its list of attributes or child nodes. If you find
+ that you need to retrieve this kind of information from your
+ query results, there are two ways to proceed.
+
+ \list
+
+ \o Send the output of your XQuery to an \l{QAbstractXmlReceiver}
+ {XML receiver}, or
+
+ \o Let your XQuery do all the work to produce the desired result.
+
+ \endlist
+
+ The second case is explained by example. Suppose you want to
+ populate a list widget with the values of certain attributes from a
+ set of result elements. You could write an XQuery to return the set
+ of elements, and then you would write the code to iterate over the
+ result elements, get their attributes, and extract the desired
+ string values. But the simpler way is to just augment your XQuery to
+ finding the desired attribute values. Then all you have to do is
+ evaluate the XQuery using the version of QXmlQuery::evaluateTo()
+ that populates a QStringList, which you can send directly to your
+ widget.
+
+ QXmlNodeModelIndex doesn't impose any restrictions on the \c data
+ value an QXmlNodeModelIndex should contain. The meaning of the data
+ left to the associated \l {QAbstractXmlNodeModel} {node model}.
+ Because QXmlNodeModelIndex depends on a particular subclass of
+ QAbstractXmlNodeModel for its existence, the only way you can create
+ an instance of QXmlNodeModelIndex is by asking the node model to
+ create one for you with QAbstractXmlNodeModel::createIndex(). Since
+ that function is protected, it is usually a good idea to write a
+ public function that creates a QXmlNodeModelIndex from arguments that
+ are appropriate for your particular node model.
+
+ A default constructed node index is said to be null, i.e., isNull()
+ returns true.
+
+ QXmlNodeModelIndex and QAbstractXmlNodeModel follow the same design
+ pattern used for QModelIndex and QAbstractItemModel.
+ */
+
+/*!
+ \since 4.4
+ \relates QHash
+
+ Computes a hash key from the QXmlNodeModelIndex \a index, and
+ returns it. This function would be used by QHash if you wanted
+ to build a hash table for instances of QXmlNodeModelIndex.
+
+ The hash is computed on QXmlNodeModelIndex::data(),
+ QXmlNodeModelIndex::additionalData(), and
+ QXmlNodeModelIndex::model(). This means the hash key can be used for
+ node indexes from different node models.
+ */
+uint qHash(const QXmlNodeModelIndex &index)
+{
+ return uint(index.data() + index.additionalData() + quintptr(index.model()));
+}
+
+/*!
+ \enum QXmlNodeModelIndex::NodeKind
+
+ Identifies a kind of node.
+
+ \value Attribute Identifies an attribute node
+ \value Text Identifies a text node
+ \value Comment Identifies a comment node
+ \value Document Identifies a document node
+ \value Element Identifies an element node
+ \value Namespace Identifies a namespace node
+ \value ProcessingInstruction Identifies a processing instruction.
+
+ Note that the optional XML declaration at very beginning of the XML
+ document is not a processing instruction
+
+ \sa QAbstractXmlNodeModel::kind()
+*/
+
+/*!
+ \typedef QXmlNodeModelIndex::List
+
+ Typedef for QList<QXmlNodeModelIndex>.
+ */
+
+/*!
+ Returns true if this node is the same as \a other. This operator
+ does not compare values, children, or names of nodes. It compares
+ node identities, i.e., whether two nodes are from the same document
+ and are found at the exact same place.
+ */
+bool QXmlNodeModelIndex::operator==(const QXmlNodeModelIndex &other) const
+{
+ return !(m_storage != other.m_storage);
+}
+
+/*!
+ Returns true if \a other is the same node as this.
+ */
+bool QXmlNodeModelIndex::operator!=(const QXmlNodeModelIndex &other) const
+{
+ return !(operator==(other));
+}
+
+/*!
+ \fn QXmlNodeModelIndex::QXmlNodeModelIndex()
+
+ Default constructor. Creates an item that is \c null.
+
+ \sa isNull()
+ */
+
+/*!
+ \fn QXmlNodeModelIndex::QXmlNodeModelIndex(const QXmlNodeModelIndex &other)
+
+ Standard copy constructor. Creates a QXmlNodeModelIndex instance that
+ is a copy of \a other.
+ */
+
+/*!
+ \fn bool QXmlNodeModelIndex::isNull() const
+
+ Returns true if this QXmlNodeModelIndex is a default constructed
+ value, otherwise false.
+
+ A null QXmlNodeModelIndex doesn't represent any node and cannot
+ be used in conjunction with QAbstractXmlNodeModel.
+ */
+
+/*!
+ \fn const QAbstractXmlNodeModel *QXmlNodeModelIndex::model() const
+
+ Returns the QAbstractXmlNodeModel that this node index refers to.
+ QXmlNodeModelIndex does not own QAbstractXmlNodeModel and does not
+ keep track of its lifetime, so this pointer will dangle if the
+ QAbstractXmlNodeModel is deallocated first.
+
+ There is no setter for the node model because instances of
+ QXmlNodeModelIndex instances are only created with
+ QAbstractXmlNodeModel::createIndex().
+*/
+
+/*!
+ \fn qint64 QXmlNodeModelIndex::data() const
+
+ Returns the first data value. The node index holds two data values.
+ additionalData() returns the second one.
+
+ \sa additionalData()
+*/
+
+/*!
+ \fn void *QXmlNodeModelIndex::internalPointer() const
+
+ Returns the first data value as a void* pointer.
+
+ \sa additionalData()
+*/
+
+/*!
+ \fn qint64 QXmlNodeModelIndex::additionalData() const
+
+ Returns the second data value. The node index holds two data values.
+ data() returns the first one.
+
+ \sa data()
+*/
+
+/*!
+ \fn void QXmlNodeModelIndex::reset()
+ \internal
+
+ Resets this QXmlNodeModelIndex to be null. It is equivalent to
+ writing:
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 0
+ */
+
+/*!
+ \fn QXmlName QXmlNodeModelIndex::name() const
+ \internal
+*/
+
+/*!
+ \typedef QXmlNodeModelIndex::Iterator
+ \internal
+
+ Typedef for QAbstractXmlForwardIterator<QXmlNodeModelIndex>.
+ */
+/*!
+ \fn QXmlNodeModelIndex QXmlNodeModelIndex::root() const
+ \internal
+*/
+
+/*!
+ \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndex::iterate(const Axis axis) const
+ \internal
+*/
+
+/*!
+ \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const
+ \internal
+*/
+
+/*!
+ \fn QUrl QXmlNodeModelIndex::documentUri() const
+ \internal
+*/
+
+/*!
+ \fn QUrl QXmlNodeModelIndex::baseUri() const
+ \internal
+*/
+
+/*!
+ \fn NodeKind QXmlNodeModelIndex::kind() const
+ \internal
+*/
+
+/*!
+ \fn bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const
+ \internal
+*/
+
+/*!
+ \fn DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const
+ \internal
+*/
+
+/*!
+ \fn void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const
+ \internal
+*/
+
+/*!
+ \fn QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const
+ \internal
+*/
+
+/*!
+ \fn QXmlNodeModelIndex QAbstractXmlNodeModel::elementById(const QXmlName &id) const
+
+ Returns the index of the element identified as \a id. XQuery's \c
+ id() function calls this function.
+
+ The node index returned will be the element node whose value is of
+ type \c ID and equals \a id, or it will be the element node that has
+ an attribute whose typed value is of type \c ID and equals \a id. If
+ there is no such element, a default constructed QXmlNodeModelIndex
+ instance is returned. The implementor guarantees that if the returned
+ node index is not null, it identifies an element.
+
+ It is not sufficient for an attribute or element to merely be called
+ \c id. Its value type must also be \c ID. However, the reserved name
+ \c xml:id is sufficient.
+
+ In \a id, the \c{namespace URI} and the \c{prefix} are undefined, and
+ the \c{local name} is the ID that should be looked up.
+
+ \sa {http://www.w3.org/TR/xpath-functions/#func-id}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.2 fn:id}
+ */
+
+/*!
+ \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::nodesByIdref(const QXmlName &idref) const
+
+ Returns the elements and/or attributes that have an \c IDREF value
+ equal to \a idref. XQuery's \c idref() function calls this function.
+
+ The implementor guarantees that the nodes identified by the returned
+ indexes are elements or attributes.
+
+ It is not sufficient for an attribute or element to merely be called
+ \c idref. It must also be of type \c IDREF. Elements must be typed as
+ \c xs:IDREF or \c xs:IDREFS, or, in the case of attributes, as \c
+ IDREF or \c IDREFS in the schema.
+
+ In \a idref, the \c{namespace URI} and the \c{prefix} are undefined,
+ and the \c{local name} is the ID that should be looked up.
+
+ \sa {http://www.w3.org/TR/xpath-functions/#func-idref}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.3 fn:idref}
+ */
+
+/*!
+ \fn QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const
+ \internal
+*/
+
+/*!
+ \fn QString QXmlNodeModelIndex::stringValue() const
+ \internal
+*/
+
+/*!
+ \fn QPatternist::ItemTypePtr QXmlNodeModelIndex::type() const
+ \internal
+*/
+
+/*!
+ \fn bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const
+ \internal
+*/
+
+/*!
+ \enum QAbstractXmlNodeModel::NodeCopySetting
+ \internal
+
+ Controls how nodes are copied with copyNodeTo.
+
+ \value InheritNamespaces Copies the node with the \c copy-namespaces
+ setting being \c inherit. If not set, \c no-inherit is assumed.
+ \value PreserveNamespaces Copies the node with the \c copy-namespaces
+ settings being \c preserve. If not set, \c no-preserve is assumed.
+ */
+
+/*!
+ \typedef QAbstractXmlNodeModel::NodeCopySettings
+ \internal
+ */
+
+/*!
+ \internal
+
+ Copies node \a node to \a receiver, steered by \a copySettings.
+
+ The caller guarantees that \a node is not \c null, and that is
+ belongs to this QAbstractXmlNodeModel instance.
+
+ The caller guarantees that \a receiver is not \c null.
+*/
+void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node,
+ QAbstractXmlReceiver *const receiver,
+ const NodeCopySettings &copySettings) const
+{
+ Q_UNUSED(node);
+ Q_UNUSED(receiver);
+ Q_UNUSED(copySettings);
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "This function is not expected to be called.");
+}
+
+/*!
+ Returns the source location for the object with the given \a index
+ or a default constructed QSourceLocation in case no location
+ information is available.
+
+ \since 4.6
+*/
+QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const
+{
+ // TODO: make this method virtual in Qt5 to allow source location support in custom models
+ if (d_ptr)
+ return d_ptr->sourceLocation(index);
+ else
+ return QSourceLocation();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.h b/src/xmlpatterns/api/qabstractxmlnodemodel.h
new file mode 100644
index 0000000..808e752
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel.h
@@ -0,0 +1,429 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTXMLNODEMODEL_H
+#define QABSTRACTXMLNODEMODEL_H
+
+#include <QtXmlPatterns/QXmlName>
+#include <QtCore/QSharedData>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+/* This file contains the classes QXmlNodeModelIndex, QAbstractXmlNodeModel,
+ * QXmlItem and QPatternist::NodeIndexStorage. */
+
+class QAbstractXmlNodeModel;
+class QAbstractXmlNodeModelPrivate;
+class QAbstractXmlReceiver;
+class QSourceLocation;
+class QUrl;
+class QXmlName;
+class QXmlNodeModelIndex;
+template<typename T> class QAbstractXmlForwardIterator;
+template<typename T> class QVector;
+
+/* The members in the namespace QPatternist are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+namespace QPatternist
+{
+ class DynamicContext;
+ class Item;
+ class ItemType;
+ class XsdValidatedXmlNodeModel;
+ template<typename TResult, typename TSource, typename TMapper, typename Context> class ItemMappingIterator;
+ template<typename TResult, typename TSource, typename TMapper> class SequenceMappingIterator;
+ typedef QExplicitlySharedDataPointer<ItemType> ItemTypePtr;
+ typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<Item> > ItemIteratorPtr;
+ typedef QVector<QXmlName> QXmlNameVector;
+
+ class NodeIndexStorage
+ {
+ public:
+ typedef qint64 Data;
+
+ /*!
+ \note Changing merely the order of these two members, ptr and data,
+ is a binary incompatible change on Mac Power PC.
+ */
+ union
+ {
+ void *ptr; // Do not use ptr directy, use pointer() instead.
+ Data data;
+ };
+ void *pointer() const
+ {
+ /* Constructing to qptrdiff means we avoid the warning "cast to pointer
+ * from integer of different size."
+ */
+ return (void *)qptrdiff(data);
+ }
+
+ Data additionalData;
+ const QAbstractXmlNodeModel *model;
+
+ /* Implementation is in qabstractxmlnodemodel.cpp. */
+ inline bool operator!=(const NodeIndexStorage &other) const;
+ };
+}
+
+class Q_XMLPATTERNS_EXPORT QXmlNodeModelIndex
+{
+ enum Constants
+ {
+ ForwardAxis = 8192,
+ ReverseAxis = 16384
+ };
+
+public:
+ inline QXmlNodeModelIndex()
+ {
+ reset();
+ }
+
+ inline QXmlNodeModelIndex(const QXmlNodeModelIndex &other) : m_storage(other.m_storage)
+ {
+ }
+
+ bool operator==(const QXmlNodeModelIndex &other) const;
+ bool operator!=(const QXmlNodeModelIndex &other) const;
+
+ typedef QAbstractXmlForwardIterator<QXmlNodeModelIndex> Iterator;
+ typedef QList<QXmlNodeModelIndex> List;
+
+ enum NodeKind
+ {
+ Attribute = 1,
+ Comment = 2,
+ Document = 4,
+ Element = 8,
+ Namespace = 16,
+ ProcessingInstruction = 32,
+ Text = 64
+ };
+
+ enum DocumentOrder
+ {
+ Precedes = -1,
+ Is = 0,
+ Follows = 1
+ };
+
+ enum Axis
+ {
+ AxisChild = 1 | ForwardAxis,
+ AxisDescendant = 2 | ForwardAxis,
+ AxisAttribute = 4 | ForwardAxis,
+ AxisSelf = 8 | ForwardAxis,
+ AxisDescendantOrSelf = 16 | ForwardAxis,
+ AxisFollowingSibling = 32 | ForwardAxis,
+ AxisNamespace = 64 | ForwardAxis,
+ AxisFollowing = 128 | ReverseAxis,
+ AxisParent = 256 | ReverseAxis,
+ AxisAncestor = 512 | ReverseAxis,
+ AxisPrecedingSibling = 1024 | ReverseAxis,
+ AxisPreceding = 2048 | ReverseAxis,
+ AxisAncestorOrSelf = 4096 | ReverseAxis,
+ /* Note that we cannot clash with the values of ForwardAxis and
+ * ReverseAxis. */
+ AxisChildOrTop = 32768 | ForwardAxis,
+ AxisAttributeOrTop = 65536 | ForwardAxis
+ };
+
+ inline qint64 data() const
+ {
+ return m_storage.data;
+ }
+
+ inline void *internalPointer() const
+ {
+ return m_storage.pointer();
+ }
+
+ inline const QAbstractXmlNodeModel *model() const
+ {
+ return m_storage.model;
+ }
+
+ inline qint64 additionalData() const
+ {
+ return m_storage.additionalData;
+ }
+
+ inline bool isNull() const
+ {
+ return !m_storage.model;
+ }
+
+ /* The members below are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+
+ inline QXmlName name() const;
+ inline QXmlNodeModelIndex root() const;
+ inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > iterate(const Axis axis) const;
+ inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > sequencedTypedValue() const;
+ inline QUrl documentUri() const;
+ inline QUrl baseUri() const;
+ inline NodeKind kind() const;
+ inline bool isDeepEqual(const QXmlNodeModelIndex &other) const;
+ inline DocumentOrder compareOrder(const QXmlNodeModelIndex &other) const;
+ inline void sendNamespaces(QAbstractXmlReceiver *const receiver) const;
+ inline QVector<QXmlName> namespaceBindings() const;
+ inline QXmlName::NamespaceCode namespaceForPrefix(const QXmlName::PrefixCode prefix) const;
+ inline QString stringValue() const;
+ inline QPatternist::ItemTypePtr type() const;
+ inline bool is(const QXmlNodeModelIndex &other) const;
+
+ inline void reset()
+ {
+ m_storage.data = 0;
+ m_storage.additionalData = 0;
+ m_storage.model = 0;
+ }
+
+private:
+ static inline QXmlNodeModelIndex create(const qint64 d,
+ const QAbstractXmlNodeModel *const nm)
+ {
+ QXmlNodeModelIndex n;
+ n.m_storage.data = d;
+ n.m_storage.model = nm;
+ n.m_storage.additionalData = 0;
+ return n;
+ }
+
+ static inline QXmlNodeModelIndex create(const qint64 data,
+ const QAbstractXmlNodeModel *const nm,
+ const qint64 addData)
+ {
+ QXmlNodeModelIndex n;
+ n.m_storage.data = data;
+ n.m_storage.model = nm;
+ n.m_storage.additionalData = addData;
+ return n;
+ }
+
+ inline QXmlNodeModelIndex(const QPatternist::NodeIndexStorage &storage) : m_storage(storage)
+ {
+ }
+
+ friend class QAbstractXmlNodeModel;
+ friend class QPatternist::Item;
+ friend class QXmlItem;
+ inline operator int() const; // Disable
+
+ QPatternist::NodeIndexStorage m_storage;
+};
+
+Q_XMLPATTERNS_EXPORT uint qHash(const QXmlNodeModelIndex &index);
+
+inline bool qIsForwardIteratorEnd(const QXmlNodeModelIndex &item)
+{
+ return item.isNull();
+}
+
+class Q_XMLPATTERNS_EXPORT QAbstractXmlNodeModel : public QSharedData
+{
+public:
+ enum SimpleAxis
+ {
+ Parent,
+ FirstChild,
+ PreviousSibling,
+ NextSibling
+ };
+
+ typedef QExplicitlySharedDataPointer<QAbstractXmlNodeModel> Ptr;
+ typedef QList<Ptr> List;
+
+ QAbstractXmlNodeModel();
+ virtual ~QAbstractXmlNodeModel();
+
+ virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const = 0;
+ virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const = 0;
+ virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const = 0;
+ virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1,
+ const QXmlNodeModelIndex &ni2) const = 0;
+ virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const = 0;
+ virtual QXmlName name(const QXmlNodeModelIndex &ni) const = 0;
+ virtual QString stringValue(const QXmlNodeModelIndex &n) const = 0;
+ virtual QVariant typedValue(const QXmlNodeModelIndex &n) const = 0;
+
+ /* The members below are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+ virtual QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > iterate(const QXmlNodeModelIndex &ni, QXmlNodeModelIndex::Axis axis) const;
+ virtual QPatternist::ItemIteratorPtr sequencedTypedValue(const QXmlNodeModelIndex &ni) const;
+ virtual QPatternist::ItemTypePtr type(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlName::NamespaceCode namespaceForPrefix(const QXmlNodeModelIndex &ni,
+ const QXmlName::PrefixCode prefix) const;
+ virtual bool isDeepEqual(const QXmlNodeModelIndex &ni1,
+ const QXmlNodeModelIndex &ni2) const;
+ virtual void sendNamespaces(const QXmlNodeModelIndex &n,
+ QAbstractXmlReceiver *const receiver) const;
+ virtual QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex &n) const = 0;
+
+
+ virtual QXmlNodeModelIndex elementById(const QXmlName &NCName) const = 0;
+ virtual QVector<QXmlNodeModelIndex> nodesByIdref(const QXmlName &NCName) const = 0;
+
+ enum NodeCopySetting
+ {
+ InheritNamespaces = 0x1,
+ PreserveNamespaces = 0x2
+ };
+
+ typedef QFlags<NodeCopySetting> NodeCopySettings;
+ virtual void copyNodeTo(const QXmlNodeModelIndex &node,
+ QAbstractXmlReceiver *const receiver,
+ const NodeCopySettings &) const;
+
+ QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const;
+
+protected:
+
+ virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const = 0;
+ virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex &element) const = 0;
+
+ QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d);
+
+ inline QXmlNodeModelIndex createIndex(qint64 data) const
+ {
+ return QXmlNodeModelIndex::create(data, this);
+ }
+
+ inline QXmlNodeModelIndex createIndex(void * pointer,
+ qint64 additionalData = 0) const
+ {
+ return QXmlNodeModelIndex::create(qptrdiff(pointer), this, additionalData);
+ }
+
+ inline QXmlNodeModelIndex createIndex(qint64 data,
+ qint64 additionalData) const
+ {
+ return QXmlNodeModelIndex::create(data, this, additionalData);
+ }
+
+ QScopedPointer<QAbstractXmlNodeModelPrivate> d_ptr;
+private:
+ friend class QPatternist::ItemMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >;
+ friend class QPatternist::SequenceMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *>;
+ friend class QPatternist::XsdValidatedXmlNodeModel;
+
+ inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > mapToSequence(const QXmlNodeModelIndex &ni,
+ const QExplicitlySharedDataPointer<QPatternist::DynamicContext> &) const;
+
+ static inline bool isIgnorableInDeepEqual(const QXmlNodeModelIndex &n);
+ Q_DISABLE_COPY(QAbstractXmlNodeModel)
+};
+
+Q_DECLARE_TYPEINFO(QXmlNodeModelIndex, Q_MOVABLE_TYPE);
+
+template<typename T> class QAbstractXmlForwardIterator;
+class QVariant;
+class QXmlItemPrivate;
+
+namespace QPatternist
+{
+ class AtomicValue;
+ class VariableLoader;
+ class IteratorBridge;
+ class ToQXmlItemMapper;
+ class ToItemMapper;
+}
+
+class Q_XMLPATTERNS_EXPORT QXmlItem
+{
+public:
+ typedef QAbstractXmlForwardIterator<QXmlItem> Iterator;
+
+ QXmlItem();
+ QXmlItem(const QXmlItem &other);
+ QXmlItem(const QXmlNodeModelIndex &node);
+ QXmlItem(const QVariant &atomicValue);
+ ~QXmlItem();
+ QXmlItem &operator=(const QXmlItem &other);
+
+ bool isNull() const;
+ bool isNode() const;
+ bool isAtomicValue() const;
+
+ QVariant toAtomicValue() const;
+ QXmlNodeModelIndex toNodeModelIndex() const;
+
+private:
+ friend class QPatternist::IteratorBridge;
+ friend class QPatternist::VariableLoader;
+ friend class QPatternist::ToQXmlItemMapper;
+ friend class QPatternist::ToItemMapper;
+ friend class QPatternist::Item;
+
+ inline bool internalIsAtomicValue() const;
+
+ inline QXmlItem(const QPatternist::Item &i);
+
+ union
+ {
+ QPatternist::NodeIndexStorage m_node;
+
+ /* These two sits at the position of NodeIndexStorage::data.
+ * NodeIndexStorage::{additionalData,model} are free. */
+ const QPatternist::AtomicValue *m_atomicValue;
+ QXmlItemPrivate * m_ptr; /* Not currently used. */
+ };
+};
+
+inline bool qIsForwardIteratorEnd(const QXmlItem &item)
+{
+ return item.isNull();
+}
+
+Q_DECLARE_TYPEINFO(QXmlItem, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QXmlItem) /* This macro must appear after QT_END_NAMESPACE. */
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel_p.h b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h
new file mode 100644
index 0000000..d4c2060
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QABSTRACTXMLNODEMODEL_P_H
+#define QABSTRACTXMLNODEMODEL_P_H
+
+#include "qabstractxmlnodemodel.h"
+#include "qsourcelocation.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractXmlNodeModelPrivate
+{
+public:
+ virtual ~QAbstractXmlNodeModelPrivate()
+ {
+ }
+
+ virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const
+ {
+ Q_UNUSED(index);
+
+ return QSourceLocation();
+ }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp
new file mode 100644
index 0000000..6dbd50b
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "qxmlname.h"
+#include "qnamepool_p.h"
+#include "qabstractxmlpullprovider_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+// TODO have example where query selects, and the events for the result are indented
+
+/*!
+ \internal
+ \class AbstractXmlPullProvider
+ \brief The AbstractXmlPullProvider class provides a pull-based stream interface for the XPath Data Model.
+ \reentrant
+ \ingroup xml-tools
+
+ AbstractXmlPullProvider allows a stream of items from the XPath Data Model -- essentially XML --
+ to be iterated over. The subclass of AbstractXmlPullProvider provides the events, and the
+ user calling next() and so on, consumes them. AbstractXmlPullProvider can be considered
+ a forward-only, non-reversible iterator.
+
+ Note that the content the events describes, are not necessarily a well-formed XML document, but
+ rather an instance of the XPath Data model, to be specific. For instance, maybe a pull provider
+ returns two atomic values, followed by an element tree, and at the end two document nodes.
+
+ If you are subclassing AbstractXmlPullProvider, be careful to correctly implement
+ the behaviors, as described for the individual members and events.
+
+ \sa AbstractXmlPullProvider::Event
+ */
+
+/*!
+ \enum AbstractXmlPullProvider::Event
+ \value StartOfInput The value AbstractXmlPullProvider::current() returns before the first call to next().
+ \value AtomicValue an atomic value such as an \c xs:integer, \c xs:hexBinary, or \c xs:dateTime. Atomic values
+ can only be top level items.
+ \value StartDocument Signals the start of a document node. Note that a AbstractXmlPullProvider can provide
+ a sequence of document nodes.
+ \value EndDocument Signals the end of a document node. StartDocument and EndDocument are always balanced
+ and always top-level events. For instance, StartDocument can never appear after any StartElement
+ events that hasn't been balanced by the corresponding amount of EndElement events.
+ \value StartElement Signals an element start tag.
+ \value EndElement Signals the end of an element. StartElement and EndElement events are always balanced.
+ \value Text Signals a text node. Adjacent text nodes cannot occur.
+ \value ProcessingInstruction A processing instruction. Its name is returned from name(), and its value in stringValue().
+ \value Comment a comment node. Its value can be retrieved with stingValue().
+ \value Attribute Signals an attribute node. Attribute events can only appear after Namespace events, or
+ if no such are sent, after the StartElement. In addition they must appear sequentially,
+ and each name must be unique. The ordering of attribute events is undefined and insignificant.
+ \value Namespace Signals a namespace binding. They occur very infrequently and are not needed for attributes
+ and elements. Namespace events can only appear after the StartElement event. The
+ ordering of namespace events is undefined and insignificant.
+ \value EndOfInput When next() is called after the last event, EndOfInput is returned.
+
+ \sa AbstractXmlPullProvider::current()
+ */
+
+/*!
+ Constucts a AbstractXmlPullProvider instance.
+ */
+AbstractXmlPullProvider::AbstractXmlPullProvider()
+{
+}
+
+/*!
+ Destructs this AbstractXmlPullProvider.
+ */
+AbstractXmlPullProvider::~AbstractXmlPullProvider()
+{
+}
+
+/*!
+ \fn Event AbstractXmlPullProvider::next() = 0;
+ Advances this AbstractXmlPullProvider, and returns the new event.
+
+ \sa current()
+ */
+
+/*!
+ \fn Event AbstractXmlPullProvider::current() const = 0;
+ Returns the event that next() returned the last time it was called. It doesn't
+ alter this AbstractXmlPullProvider.
+
+ current() may not modify this AbstractXmlPullProvider's state. Subsequent calls to current()
+ must return the same value.
+
+ \sa AbstractXmlPullProvider::Event
+ */
+
+/*!
+ \fn QName AbstractXmlPullProvider::name() const = 0;
+ If the current event is StartElement,
+ EndElement, ProcessingInstruction, Attribute, or Namespace, the node's name is returned.
+
+ If the current event is ProcessingInstruction,
+ the processing instruction target is in in the local name.
+
+ If the current event is Namespace, the name's namespace URI is the namespace, and
+ the local name is the prefix the name is binding to.
+
+ In all other cases, an invalid QName is returned.
+ */
+
+/*!
+ \fn QVariant AbstractXmlPullProvider::atomicValue() const = 0;
+
+ If current() event is AtomicValue, the atomic value is returned as a QVariant.
+ In all other cases, this function returns a null QVariant.
+ */
+
+/*!
+ \fn QString AbstractXmlPullProvider::stringValue() const = 0;
+
+ If current() is Text, the text node's value is returned.
+
+ If the current() event is Comment, its value is returned. The subclasser guarantees
+ it does not contain the string "-->".
+
+ If the current() event is ProcessingInstruction, its data is returned. The subclasser
+ guarantees the data does not contain the string "?>".
+
+ In other cases, it returns a default constructed string.
+ */
+
+/*!
+ \fn QHash<QXmlName, QString> AbstractXmlPullProvider::attributes() = 0;
+
+ If the current() is Element, the attributes of the element are returned,
+ an empty list of attributes otherwise.
+ */
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h
new file mode 100644
index 0000000..547bf4b
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QABSTRACTXMLPULLPROVIDER_H
+#define QABSTRACTXMLPULLPROVIDER_H
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlItem;
+class QXmlName;
+class QString;
+class QVariant;
+template<typename Key, typename Value> class QHash;
+
+namespace QPatternist
+{
+ class AbstractXmlPullProviderPrivate;
+
+ class AbstractXmlPullProvider
+ {
+ public:
+ AbstractXmlPullProvider();
+ virtual ~AbstractXmlPullProvider();
+
+ enum Event
+ {
+ StartOfInput = 1,
+ AtomicValue = 1 << 1,
+ StartDocument = 1 << 2,
+ EndDocument = 1 << 3,
+ StartElement = 1 << 4,
+ EndElement = 1 << 5,
+ Text = 1 << 6,
+ ProcessingInstruction = 1 << 7,
+ Comment = 1 << 8,
+ Attribute = 1 << 9,
+ Namespace = 1 << 10,
+ EndOfInput = 1 << 11
+ };
+
+ virtual Event next() = 0;
+ virtual Event current() const = 0;
+ virtual QXmlName name() const = 0;
+ virtual QVariant atomicValue() const = 0;
+ virtual QString stringValue() const = 0;
+
+ virtual QHash<QXmlName, QString> attributes() = 0;
+ virtual QHash<QXmlName, QXmlItem> attributeItems() = 0;
+
+ /* *** The functions below are internal. */
+ private:
+ Q_DISABLE_COPY(AbstractXmlPullProvider)
+ AbstractXmlPullProviderPrivate *d;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qabstractxmlreceiver.cpp b/src/xmlpatterns/api/qabstractxmlreceiver.cpp
new file mode 100644
index 0000000..2b7c295
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlreceiver.cpp
@@ -0,0 +1,475 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+
+#include "qitem_p.h"
+
+#include "qabstractxmlreceiver_p.h"
+#include "qabstractxmlreceiver.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstractXmlReceiver
+ \brief The QAbstractXmlReceiver class provides a callback interface
+ for transforming the output of a QXmlQuery.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ QAbstractXmlReceiver is an abstract base class that provides
+ a callback interface for receiving an \l {XQuery Sequence}
+ {XQuery sequence}, usually the output of an QXmlQuery, and
+ transforming that sequence into a structure of your choosing,
+ usually XML. Consider the example:
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0
+
+ First it constructs a \l {QXmlQuery} {query} that gets the
+ first paragraph from document \c index.html. Then it constructs
+ an \l {QXmlSerializer} {XML serializer} with the \l {QXmlQuery}
+ {query} and \l {QIODevice} {myOutputDevice} (Note the
+ \l {QXmlSerializer} {serializer} is an \e {XML receiver},
+ ie a subclass of QAbstractXmlReceiver). Finally, it
+ \l {QXmlQuery::evaluateTo()} {evaluates} the
+ \l {QXmlQuery} {query}, producing an ordered sequence of calls
+ to the \l {QXmlSerializer} {serializer's} callback functions.
+ The sequence of callbacks transforms the query output to XML
+ and writes it to \l {QIODevice} {myOutputDevice}.
+
+ Although the example uses \l {QXmlQuery} to produce the sequence
+ of callbacks to functions in QAbstractXmlReceiver, you can call
+ the callback functions directly as long as your sequence of
+ calls represents a valid \l {XQuery Sequence} {XQuery sequence}.
+
+ \target XQuery Sequence
+ \section1 XQuery Sequences
+
+ An XQuery \a sequence is an ordered collection of zero, one,
+ or many \e items. Each \e item is either an \e {atomic value}
+ or a \e {node}. An \e {atomic value} is a simple data value.
+
+ There are six kinds of \e nodes.
+
+ \list
+
+ \o An \e {Element Node} represents an XML element.
+
+ \o An \e {Attribute Node} represents an XML attribute.
+
+ \o A \e {Document Node} represents an entire XML document.
+
+ \o A \e {Text Node} represents character data (element content).
+
+ \o A \e {Processing Instruction Node} represents an XML
+ processing instruction, which is used in an XML document
+ to tell the application reading the document to perform
+ some action. A typical example is to use a processing
+ instruction to tell the application to use a particular
+ XSLT stylesheet to display the document.
+
+ \o And a \e {Comment node} represents an XML comment.
+
+ \endlist
+
+ The \e sequence of \e nodes and \e {atomic values} obeys
+ the following rules. Note that \e {Namespace Node} refers
+ to a special \e {Attribute Node} with name \e {xmlns}.
+
+ \list
+
+ \o Each \e node appears in the \e sequence before its children
+ and their descendants appear.
+
+ \o A \e node's descendants appear in the \e sequence before
+ any of its siblings appear.
+
+ \o A \e {Document Node} represents an entire document. Zero or
+ more \e {Document Nodes} can appear in a \e sequence, but they
+ can only be top level items (i.e., a \e {Document Node} can't
+ be a child of another \e node.
+
+ \o \e {Namespace Nodes} immediately follow the \e {Element Node}
+ with which they are associated.
+
+ \o \e {Attribute Nodes} immediately follow the \e {Namespace Nodes}
+ of the element with which they are associated, or...
+
+ \o If there are no \e {Namespace Nodes} following an element, then
+ the \e {Attribute Nodes} immediately follow the element.
+
+ \o An \e {atomic value} can only appear as a top level \e item,
+ i.e., it can't appear as a child of a \e node.
+
+ \o \e {Processing Instruction Nodes} do not have children, and
+ their parent is either a \e {Document Node} or an \e {Element
+ Node}.
+
+ \o \e {Comment Nodes} do not have children, and
+ their parent is either a \e {Document Node} or an \e {Element
+ Node}.
+
+ \endlist
+
+ The \e sequence of \e nodes and \e {atomic values} is sent to
+ an QAbstractXmlReceiver (QXmlSerializer in
+ the example above) as a sequence of calls to the receiver's
+ callback functions. The mapping of callback functions to
+ sequence items is as follows.
+
+ \list
+
+ \o startDocument() and endDocument() are called for each
+ \e {Document Node} in the \e sequence. endDocument() is not
+ called until all the \e {Document Node's} children have
+ appeared in the \e sequence.
+
+ \o startElement() and endElement() are called for each
+ \e {Element Node}. endElement() is not called until all the
+ \e {Element Node's} children have appeared in the \e sequence.
+
+ \o attribute() is called for each \e {Attribute Node}.
+
+ \o comment() is called for each \e {Comment Node}.
+
+ \o characters() is called for each \e {Text Node}.
+
+ \o processingInstruction() is called for each \e {Processing
+ Instruction Node}.
+
+ \o namespaceBinding() is called for each \e {Namespace Node}.
+
+ \o atomicValue() is called for each \e {atomic value}.
+
+ \endlist
+
+ For a complete explanation of XQuery sequences, visit
+ \l {http://www.w3.org/TR/xpath-datamodel/}{XQuery Data Model}.
+
+ \sa {http://www.w3.org/TR/xpath-datamodel/}{W3C XQuery 1.0 and XPath 2.0 Data Model (XDM)}
+ \sa QXmlSerializer
+ \sa QXmlResultItems
+ */
+
+template<const QXmlNodeModelIndex::Axis axis>
+void QAbstractXmlReceiver::sendFromAxis(const QXmlNodeModelIndex &node)
+{
+ Q_ASSERT(!node.isNull());
+ const QXmlNodeModelIndex::Iterator::Ptr it(node.iterate(axis));
+ QXmlNodeModelIndex next(it->next());
+
+ while(!next.isNull())
+ {
+ sendAsNode(next);
+ next = it->next();
+ }
+}
+
+/*!
+ \internal
+ */
+QAbstractXmlReceiver::QAbstractXmlReceiver(QAbstractXmlReceiverPrivate *d)
+ : d_ptr(d)
+{
+}
+
+/*!
+ Constructs an abstract xml receiver.
+ */
+QAbstractXmlReceiver::QAbstractXmlReceiver() : d_ptr(0)
+{
+}
+
+/*!
+ Destroys the xml receiver.
+ */
+QAbstractXmlReceiver::~QAbstractXmlReceiver()
+{
+}
+
+/*!
+ \fn void QAbstractXmlReceiver::startElement(const QXmlName &name)
+
+ This callback is called when a new element node appears
+ in the \l {XQuery Sequence} {sequence}. \a name is the
+ valid \l {QXmlName} {name} of the node element.
+ */
+
+/*
+### Qt 5:
+
+Consider how source locations should be communicated. Maybe every signature
+should be extended by adding "qint64 line = -1, qint64 column = -1".
+ */
+
+/*!
+ \fn void QAbstractXmlReceiver::endElement()
+
+ This callback is called when the end of an element node
+ appears in the \l {XQuery Sequence} {sequence}.
+*/
+
+/*!
+ \fn void QAbstractXmlReceiver::attribute(const QXmlName &name,
+ const QStringRef &value)
+ This callback is called when an attribute node
+ appears in the \l {XQuery Sequence} {sequence}.
+ \a name is the \l {QXmlName} {attribute name} and
+ the \a value string contains the attribute value.
+ */
+
+/*!
+ \fn void QAbstractXmlReceiver::comment(const QString &value)
+
+ This callback is called when a comment node appears
+ in the \l {XQuery Sequence} {sequence}. The \a value
+ is the comment text, which must not contain the string
+ "--".
+ */
+
+/*!
+ \fn void QAbstractXmlReceiver::characters(const QStringRef &value)
+
+ This callback is called when a text node appears in the
+ \l {XQuery Sequence} {sequence}. The \a value contains
+ the text. Adjacent text nodes may not occur in the
+ \l {XQuery Sequence} {sequence}, i.e., this callback must not
+ be called twice in a row.
+ */
+
+/*!
+ \fn void QAbstractXmlReceiver::startDocument()
+
+ This callback is called when a document node appears
+ in the \l {XQuery Sequence} {sequence}.
+ */
+
+/*
+### Qt 5:
+
+Change
+ virtual void startDocument() = 0;
+
+To:
+ virtual void startDocument(const QUrl &uri) = 0;
+
+Such that it allows the document URI to be communicated. The contract would
+allow null QUrls.
+*/
+
+/*!
+ \fn void QAbstractXmlReceiver::endDocument()
+
+ This callback is called when the end of a document node
+ appears in the \l {XQuery Sequence} {sequence}.
+ */
+
+/*!
+ \fn void QAbstractXmlReceiver::processingInstruction(const QXmlName &target,
+ const QString &value)
+
+ This callback is called when a processing instruction
+ appears in the \l {XQuery Sequence} {sequence}.
+ A processing instruction is used in an XML document
+ to tell the application reading the document to
+ perform some action. A typical example is to use a
+ processing instruction to tell the application to use a
+ particular XSLT stylesheet to process the document.
+
+ \quotefile doc/src/snippets/patternist/xmlStylesheet.xq
+
+ \a target is the \l {QXmlName} {name} of the processing
+ instruction. Its \e prefix and \e {namespace URI} must both
+ be empty. Its \e {local name} is the target. In the above
+ example, the name is \e {xml-stylesheet}.
+
+ The \a value specifies the action to be taken. Note that
+ the \a value must not contain the string "?>". In the above
+ example, the \a value is \e{type="test/xsl" href="formatter.xsl}.
+
+ Generally, use of processing instructions should be avoided,
+ because they are not namespace aware and in many contexts
+ are stripped out anyway. Processing instructions can often
+ be replaced with elements from a custom namespace.
+ */
+
+/*!
+ \fn void QAbstractXmlReceiver::atomicValue(const QVariant &value)
+
+ This callback is called when an atomic value appears in the \l
+ {XQuery Sequence} {sequence}. The \a value is a simple \l {QVariant}
+ {data value}. It is guaranteed to be \l {QVariant::isValid()}
+ {valid}.
+ */
+
+/*!
+ \fn virtual void QAbstractXmlReceiver::namespaceBinding(const QXmlName &name)
+
+ This callback is called when a namespace binding is in scope of an
+ element. A namespace is defined by a URI. In the \l {QXmlName}
+ \a name, the value of \l {QXmlName::namespaceUri()} is that URI. The
+ value of \l {QXmlName::prefix()} is the prefix that the URI is bound
+ to. The local name is insignificant and can be an arbitrary value.
+ */
+
+/*!
+ \internal
+
+ Treats \a outputItem as a node and calls the appropriate function,
+ e.g., attribute() or comment(), depending on its
+ QXmlNodeModelIndex::NodeKind.
+
+ This is a helper function that subclasses can use to multiplex
+ Nodes received via item().
+ */
+void QAbstractXmlReceiver::sendAsNode(const QPatternist::Item &outputItem)
+{
+ Q_ASSERT(outputItem);
+ Q_ASSERT(outputItem.isNode());
+ const QXmlNodeModelIndex asNode = outputItem.asNode();
+
+ switch(asNode.kind())
+ {
+ case QXmlNodeModelIndex::Attribute:
+ {
+ const QString &v = outputItem.stringValue();
+ attribute(asNode.name(), QStringRef(&v));
+ return;
+ }
+ case QXmlNodeModelIndex::Element:
+ {
+ startElement(asNode.name());
+
+ /* First the namespaces, then attributes, then the children. */
+ asNode.sendNamespaces(this);
+ sendFromAxis<QXmlNodeModelIndex::AxisAttribute>(asNode);
+ sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
+
+ endElement();
+
+ return;
+ }
+ case QXmlNodeModelIndex::Text:
+ {
+ const QString &v = asNode.stringValue();
+ characters(QStringRef(&v));
+ return;
+ }
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ {
+ processingInstruction(asNode.name(), outputItem.stringValue());
+ return;
+ }
+ case QXmlNodeModelIndex::Comment:
+ {
+ comment(outputItem.stringValue());
+ return;
+ }
+ case QXmlNodeModelIndex::Document:
+ {
+ startDocument();
+ sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
+ endDocument();
+ return;
+ }
+ case QXmlNodeModelIndex::Namespace:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
+ }
+
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ QString::fromLatin1("Unknown node type: %1").arg(asNode.kind()).toUtf8().constData());
+}
+
+/*!
+ \internal
+
+ This function may be called instead of characters() if, and only if,
+ \a value consists only of whitespace.
+
+ The caller gurantees that \a value is not empty.
+
+ \e Whitespace refers to a sequence of characters that are either
+ spaces, tabs, or newlines, in any order. In other words, not all
+ the Unicode whitespace category is considered whitespace here.
+
+ However, there is no guarantee or requirement that whitespaceOnly()
+ is called for text nodes containing whitespace only. characters()
+ may be called just as well. This is why the default implementation
+ for whitespaceOnly() calls characters().
+
+ \sa characters()
+ */
+void QAbstractXmlReceiver::whitespaceOnly(const QStringRef &value)
+{
+ Q_ASSERT_X(value.toString().trimmed().isEmpty(), Q_FUNC_INFO,
+ "The caller must guarantee only whitespace is passed. Use characters() in other cases.");
+ const QString &v = value.toString();
+ characters(QStringRef(&v));
+}
+
+/*!
+ \internal
+ */
+void QAbstractXmlReceiver::item(const QPatternist::Item &item)
+{
+ if(item.isNode())
+ return sendAsNode(item);
+ else
+ atomicValue(QPatternist::AtomicValue::toQt(item.asAtomicValue()));
+}
+
+/*!
+ \fn void QAbstractXmlReceiver::startOfSequence()
+
+ This callback is called once only, right before the
+ \l {XQuery Sequence} {sequence} begins.
+ */
+
+/*!
+ \fn void QAbstractXmlReceiver::endOfSequence()
+
+ This callback is called once only, right after the
+ \l {XQuery Sequence} {sequence} ends.
+ */
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qabstractxmlreceiver.h b/src/xmlpatterns/api/qabstractxmlreceiver.h
new file mode 100644
index 0000000..0407730
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlreceiver.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTXMLRECEIVER_H
+#define QABSTRACTXMLRECEIVER_H
+
+#include <QtCore/QVariant>
+#include <QtCore/QScopedPointer>
+#include <QtXmlPatterns/QXmlNodeModelIndex>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QAbstractXmlReceiverPrivate;
+class QXmlName;
+
+namespace QPatternist
+{
+ class Item;
+}
+
+class Q_XMLPATTERNS_EXPORT QAbstractXmlReceiver
+{
+public:
+ QAbstractXmlReceiver();
+
+ virtual ~QAbstractXmlReceiver();
+
+ virtual void startElement(const QXmlName &name) = 0;
+ virtual void endElement() = 0;
+ virtual void attribute(const QXmlName &name,
+ const QStringRef &value) = 0;
+ virtual void comment(const QString &value) = 0;
+ virtual void characters(const QStringRef &value) = 0;
+ virtual void startDocument() = 0;
+ virtual void endDocument() = 0;
+
+ virtual void processingInstruction(const QXmlName &target,
+ const QString &value) = 0;
+
+ virtual void atomicValue(const QVariant &value) = 0;
+ virtual void namespaceBinding(const QXmlName &name) = 0;
+ virtual void startOfSequence() = 0;
+ virtual void endOfSequence() = 0;
+
+ /* The members below are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+ virtual void whitespaceOnly(const QStringRef &value);
+ virtual void item(const QPatternist::Item &item);
+
+protected:
+ QAbstractXmlReceiver(QAbstractXmlReceiverPrivate *d);
+ QScopedPointer<QAbstractXmlReceiverPrivate> d_ptr;
+
+ void sendAsNode(const QPatternist::Item &outputItem);
+private:
+ template<const QXmlNodeModelIndex::Axis axis>
+ void sendFromAxis(const QXmlNodeModelIndex &node);
+ Q_DISABLE_COPY(QAbstractXmlReceiver)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qabstractxmlreceiver_p.h b/src/xmlpatterns/api/qabstractxmlreceiver_p.h
new file mode 100644
index 0000000..34fd546
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlreceiver_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QABSTRACTXMLRECEIVER_P_H
+#define QABSTRACTXMLRECEIVER_P_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractXmlReceiverPrivate
+{
+public:
+ virtual ~QAbstractXmlReceiverPrivate()
+ {
+ }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qcoloringmessagehandler.cpp b/src/xmlpatterns/api/qcoloringmessagehandler.cpp
new file mode 100644
index 0000000..83dbaee
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloringmessagehandler.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QXmlStreamReader>
+
+#include "qcoloringmessagehandler_p.h"
+#include "qxmlpatternistcli_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ColoringMessageHandler::ColoringMessageHandler(QObject *parent) : QAbstractMessageHandler(parent)
+{
+ m_classToColor.insert(QLatin1String("XQuery-data"), Data);
+ m_classToColor.insert(QLatin1String("XQuery-expression"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-function"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-keyword"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-type"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-uri"), Data);
+ m_classToColor.insert(QLatin1String("XQuery-filepath"), Data);
+
+ /* If you're tuning the colors, take it easy laddie. Take into account:
+ *
+ * - Get over your own taste, there's others too on this planet
+ * - Make sure it works well on black & white
+ * - Make sure it works well on white & black
+ */
+ insertMapping(Location, CyanForeground);
+ insertMapping(ErrorCode, RedForeground);
+ insertMapping(Keyword, BlueForeground);
+ insertMapping(Data, BlueForeground);
+ insertMapping(RunningText, DefaultColor);
+}
+
+void ColoringMessageHandler::handleMessage(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier,
+ const QSourceLocation &sourceLocation)
+{
+ const bool hasLine = sourceLocation.line() != -1;
+
+ switch(type)
+ {
+ case QtWarningMsg:
+ {
+ if(hasLine)
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Warning in %1, at line %2, column %3: %4").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()),
+ QString::number(sourceLocation.line()),
+ QString::number(sourceLocation.column()),
+ colorifyDescription(description)));
+ }
+ else
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Warning in %1: %2").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()),
+ colorifyDescription(description)));
+ }
+
+ break;
+ }
+ case QtFatalMsg:
+ {
+ const QString errorCode(identifier.fragment());
+ Q_ASSERT(!errorCode.isEmpty());
+ QUrl uri(identifier);
+ uri.setFragment(QString());
+
+ QString location;
+
+ if(sourceLocation.isNull())
+ location = QXmlPatternistCLI::tr("Unknown location");
+ else
+ location = QString::fromLatin1(sourceLocation.uri().toEncoded());
+
+ QString errorId;
+ /* If it's a standard error code, we don't want to output the
+ * whole URI. */
+ if(uri.toString() == QLatin1String("http://www.w3.org/2005/xqt-errors"))
+ errorId = errorCode;
+ else
+ errorId = QString::fromLatin1(identifier.toEncoded());
+
+ if(hasLine)
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2, at line %3, column %4: %5").arg(colorify(errorId, ErrorCode),
+ colorify(location, Location),
+ colorify(QString::number(sourceLocation.line()), Location),
+ colorify(QString::number(sourceLocation.column()), Location),
+ colorifyDescription(description)));
+ }
+ else
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2: %3").arg(colorify(errorId, ErrorCode),
+ colorify(location, Location),
+ colorifyDescription(description)));
+ }
+ break;
+ }
+ case QtCriticalMsg:
+ /* Fallthrough. */
+ case QtDebugMsg:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "message() is not supposed to receive QtCriticalMsg or QtDebugMsg.");
+ return;
+ }
+ }
+}
+
+QString ColoringMessageHandler::colorifyDescription(const QString &in) const
+{
+ QXmlStreamReader reader(in);
+ QString result;
+ result.reserve(in.size());
+ ColorType currentColor = RunningText;
+
+ while(!reader.atEnd())
+ {
+ reader.readNext();
+
+ switch(reader.tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(reader.name() == QLatin1String("span"))
+ {
+ Q_ASSERT(m_classToColor.contains(reader.attributes().value(QLatin1String("class")).toString()));
+ currentColor = m_classToColor.value(reader.attributes().value(QLatin1String("class")).toString());
+ }
+
+ continue;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ result.append(colorify(reader.text().toString(), currentColor));
+ continue;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ currentColor = RunningText;
+ continue;
+ }
+ /* Fallthrough, */
+ case QXmlStreamReader::StartDocument:
+ /* Fallthrough, */
+ case QXmlStreamReader::EndDocument:
+ continue;
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Unexpected node.");
+ }
+ }
+
+ Q_ASSERT_X(!reader.hasError(), Q_FUNC_INFO,
+ "The output from Patternist must be well-formed.");
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qcoloringmessagehandler_p.h b/src/xmlpatterns/api/qcoloringmessagehandler_p.h
new file mode 100644
index 0000000..223bed6
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloringmessagehandler_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the XMLPatterns 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ColoringMessageHandler_h
+#define Patternist_ColoringMessageHandler_h
+
+#include <QHash>
+
+#include "qcoloroutput_p.h"
+#include "qabstractmessagehandler.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ColoringMessageHandler : public QAbstractMessageHandler
+ , private ColorOutput
+ {
+ public:
+ ColoringMessageHandler(QObject *parent = 0);
+
+ protected:
+ virtual void handleMessage(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier,
+ const QSourceLocation &sourceLocation);
+
+ private:
+ QString colorifyDescription(const QString &in) const;
+
+ enum ColorType
+ {
+ RunningText,
+ Location,
+ ErrorCode,
+ Keyword,
+ Data
+ };
+
+ QHash<QString, ColorType> m_classToColor;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qcoloroutput.cpp b/src/xmlpatterns/api/qcoloroutput.cpp
new file mode 100644
index 0000000..9ba7430
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloroutput.cpp
@@ -0,0 +1,377 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QFile>
+#include <QHash>
+#include <QTextCodec>
+
+#include "qcoloroutput_p.h"
+
+// TODO: rename insertMapping() to insertColorMapping()
+// TODO: Use a smart pointer for managing ColorOutputPrivate *d;
+// TODO: break out the C++ example into a snippet file
+
+/* This include must appear here, because if it appears at the beginning of the file for
+ * instance, it breaks build -- "qglobal.h:628: error: template with
+ * C linkage" -- on Mac OS X 10.4. */
+#ifndef Q_OS_WIN
+#include <unistd.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ class ColorOutputPrivate
+ {
+ public:
+ ColorOutputPrivate() : currentColorID(-1)
+
+ {
+ /* - QIODevice::Unbuffered because we want it to appear when the user actually calls, performance
+ * is considered of lower priority.
+ */
+ m_out.open(stderr, QIODevice::WriteOnly | QIODevice::Unbuffered);
+
+ coloringEnabled = isColoringPossible();
+ }
+
+ ColorOutput::ColorMapping colorMapping;
+ int currentColorID;
+ bool coloringEnabled;
+
+ static const char *const foregrounds[];
+ static const char *const backgrounds[];
+
+ inline void write(const QString &msg)
+ {
+ m_out.write(msg.toLocal8Bit());
+ }
+
+ static QString escapeCode(const QString &in)
+ {
+ QString result;
+ result.append(QChar(0x1B));
+ result.append(QLatin1Char('['));
+ result.append(in);
+ result.append(QLatin1Char('m'));
+ return result;
+ }
+
+ private:
+ QFile m_out;
+
+ /*!
+ Returns true if it's suitable to send colored output to \c stderr.
+ */
+ inline bool isColoringPossible() const
+ {
+# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+ /* Windows doesn't at all support ANSI escape codes, unless
+ * the user install a "device driver". See the Wikipedia links in the
+ * class documentation for details. */
+ return false;
+# else
+ /* We use QFile::handle() to get the file descriptor. It's a bit unsure
+ * whether it's 2 on all platforms and in all cases, so hopefully this layer
+ * of abstraction helps handle such cases. */
+ return isatty(m_out.handle());
+# endif
+ }
+ };
+}
+
+const char *const ColorOutputPrivate::foregrounds[] =
+{
+ "0;30",
+ "0;34",
+ "0;32",
+ "0;36",
+ "0;31",
+ "0;35",
+ "0;33",
+ "0;37",
+ "1;30",
+ "1;34",
+ "1;32",
+ "1;36",
+ "1;31",
+ "1;35",
+ "1;33",
+ "1;37"
+};
+
+const char *const ColorOutputPrivate::backgrounds[] =
+{
+ "0;40",
+ "0;44",
+ "0;42",
+ "0;46",
+ "0;41",
+ "0;45",
+ "0;43"
+};
+
+/*!
+ \class ColorOutput
+ \since 4.4
+ \nonreentrant
+ \brief Outputs colored messages to \c stderr.
+ \internal
+
+ ColorOutput is a convenience class for outputting messages to \c
+ stderr using color escape codes, as mandated in ECMA-48. ColorOutput
+ will only color output when it is detected to be suitable. For
+ instance, if \c stderr is detected to be attached to a file instead
+ of a TTY, no coloring will be done.
+
+ ColorOutput does its best attempt. but it is generally undefined
+ what coloring or effect the various coloring flags has. It depends
+ strongly on what terminal software that is being used.
+
+ When using `echo -e 'my escape sequence'`, \c{\033} works as an
+ initiator but not when printing from a C++ program, despite having
+ escaped the backslash. That's why we below use characters with
+ value 0x1B.
+
+ It can be convenient to subclass ColorOutput with a private scope,
+ such that the functions are directly available in the class using
+ it.
+
+ \section1 Usage
+
+ To output messages, call write() or writeUncolored(). write() takes
+ as second argument an integer, which ColorOutput uses as a lookup
+ key to find the color it should color the text in. The mapping from
+ keys to colors is done using insertMapping(). Typically this is used
+ by having enums for the various kinds of messages, which
+ subsequently are registered.
+
+ \code
+ enum MyMessage
+ {
+ Error,
+ Important
+ };
+
+ ColorOutput output;
+ output.insertMapping(Error, ColorOutput::RedForeground);
+ output.insertMapping(Import, ColorOutput::BlueForeground);
+
+ output.write("This is important", Important);
+ output.write("Jack, I'm only the selected official!", Error);
+ \endcode
+
+ \sa {http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html} {Bash Prompt HOWTO, 6.1. Colours}
+ {http://linuxgazette.net/issue51/livingston-blade.html} {Linux Gazette, Tweaking Eterm, Edward Livingston-Blade}
+ {http://www.ecma-international.org/publications/standards/Ecma-048.htm} {Standard ECMA-48, Control Functions for Coded Character Sets, ECMA International},
+ {http://en.wikipedia.org/wiki/ANSI_escape_code} {Wikipedia, ANSI escape code}
+ {http://linuxgazette.net/issue65/padala.html} {Linux Gazette, So You Like Color!, Pradeep Padala}
+ */
+
+/*!
+ \enum ColorOutput::ColorCodeComponent
+ \value BlackForeground
+ \value BlueForeground
+ \value GreenForeground
+ \value CyanForeground
+ \value RedForeground
+ \value PurpleForeground
+ \value BrownForeground
+ \value LightGrayForeground
+ \value DarkGrayForeground
+ \value LightBlueForeground
+ \value LightGreenForeground
+ \value LightCyanForeground
+ \value LightRedForeground
+ \value LightPurpleForeground
+ \value YellowForeground
+ \value WhiteForeground
+ \value BlackBackground
+ \value BlueBackground
+ \value GreenBackground
+ \value CyanBackground
+ \value RedBackground
+ \value PurpleBackground
+ \value BrownBackground
+
+ \value DefaultColor ColorOutput performs no coloring. This typically
+ means black on white or white on black, depending
+ on the settings of the user's terminal.
+ */
+
+/*!
+ Sets the color mapping to be \a cMapping.
+
+ Negative values are disallowed.
+
+ \sa colorMapping(), insertMapping()
+ */
+void ColorOutput::setColorMapping(const ColorMapping &cMapping)
+{
+ d->colorMapping = cMapping;
+}
+
+/*!
+ Returns the color mappings in use.
+
+ \sa setColorMapping(), insertMapping()
+ */
+ColorOutput::ColorMapping ColorOutput::colorMapping() const
+{
+ return d->colorMapping;
+}
+
+/*!
+ Constructs a ColorOutput instance, ready for use.
+ */
+ColorOutput::ColorOutput() : d(new ColorOutputPrivate())
+{
+}
+
+/*!
+ Destructs this ColorOutput instance.
+ */
+ColorOutput::~ColorOutput()
+{
+ delete d;
+}
+
+/*!
+ Sends \a message to \c stderr, using the color looked up in colorMapping() using \a colorID.
+
+ If \a color isn't available in colorMapping(), result and behavior is undefined.
+
+ If \a colorID is 0, which is the default value, the previously used coloring is used. ColorOutput
+ is initialized to not color at all.
+
+ If \a message is empty, effects are undefined.
+
+ \a message will be printed as is. For instance, no line endings will be inserted.
+ */
+void ColorOutput::write(const QString &message, int colorID)
+{
+ d->write(colorify(message, colorID));
+}
+
+/*!
+ Writes \a message to \c stderr as if for instance
+ QTextStream would have been used, and adds a line ending at the end.
+
+ This function can be practical to use such that one can use ColorOutput for all forms of writing.
+ */
+void ColorOutput::writeUncolored(const QString &message)
+{
+ d->write(message + QLatin1Char('\n'));
+}
+
+/*!
+ Treats \a message and \a colorID identically to write(), but instead of writing
+ \a message to \c stderr, it is prepared for being written to \c stderr, but is then
+ returned.
+
+ This is useful when the colored string is inserted into a translated string(dividing
+ the string into several small strings prevents proper translation).
+ */
+QString ColorOutput::colorify(const QString &message, int colorID) const
+{
+ Q_ASSERT_X(colorID == -1 || d->colorMapping.contains(colorID), Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("There is no color registered by id %1").arg(colorID)));
+ Q_ASSERT_X(!message.isEmpty(), Q_FUNC_INFO, "It makes no sense to attempt to print an empty string.");
+
+ if(colorID != -1)
+ d->currentColorID = colorID;
+
+ if(d->coloringEnabled && colorID != -1)
+ {
+ const int color(d->colorMapping.value(colorID));
+
+ /* If DefaultColor is set, we don't want to color it. */
+ if(color & DefaultColor)
+ return message;
+
+ const int foregroundCode = (int(color) & ForegroundMask) >> ForegroundShift;
+ const int backgroundCode = (int(color) & BackgroundMask) >> BackgroundShift;
+ QString finalMessage;
+ bool closureNeeded = false;
+
+ if(foregroundCode)
+ {
+ finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::foregrounds[foregroundCode - 1])));
+ closureNeeded = true;
+ }
+
+ if(backgroundCode)
+ {
+ finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::backgrounds[backgroundCode - 1])));
+ closureNeeded = true;
+ }
+
+ finalMessage.append(message);
+
+ if(closureNeeded)
+ {
+ finalMessage.append(QChar(0x1B));
+ finalMessage.append(QLatin1String("[0m"));
+ }
+
+ return finalMessage;
+ }
+ else
+ return message;
+}
+
+/*!
+ Adds a color mapping from \a colorID to \a colorCode, for this ColorOutput instance.
+
+ This is a convenience function for creating a ColorOutput::ColorMapping instance and
+ calling setColorMapping().
+
+ \sa colorMapping(), setColorMapping()
+ */
+void ColorOutput::insertMapping(int colorID, const ColorCode colorCode)
+{
+ d->colorMapping.insert(colorID, colorCode);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qcoloroutput_p.h b/src/xmlpatterns/api/qcoloroutput_p.h
new file mode 100644
index 0000000..020cfc2
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloroutput_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the XMLPatterns 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ColorOutput_h
+#define Patternist_ColorOutput_h
+
+#include <QtCore/QtGlobal>
+#include <QtCore/QHash>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ColorOutputPrivate;
+
+ class ColorOutput
+ {
+ enum
+ {
+ ForegroundShift = 10,
+ BackgroundShift = 20,
+ SpecialShift = 20,
+ ForegroundMask = ((1 << ForegroundShift) - 1) << ForegroundShift,
+ BackgroundMask = ((1 << BackgroundShift) - 1) << BackgroundShift
+ };
+
+ public:
+ enum ColorCodeComponent
+ {
+ BlackForeground = 1 << ForegroundShift,
+ BlueForeground = 2 << ForegroundShift,
+ GreenForeground = 3 << ForegroundShift,
+ CyanForeground = 4 << ForegroundShift,
+ RedForeground = 5 << ForegroundShift,
+ PurpleForeground = 6 << ForegroundShift,
+ BrownForeground = 7 << ForegroundShift,
+ LightGrayForeground = 8 << ForegroundShift,
+ DarkGrayForeground = 9 << ForegroundShift,
+ LightBlueForeground = 10 << ForegroundShift,
+ LightGreenForeground = 11 << ForegroundShift,
+ LightCyanForeground = 12 << ForegroundShift,
+ LightRedForeground = 13 << ForegroundShift,
+ LightPurpleForeground = 14 << ForegroundShift,
+ YellowForeground = 15 << ForegroundShift,
+ WhiteForeground = 16 << ForegroundShift,
+
+ BlackBackground = 1 << BackgroundShift,
+ BlueBackground = 2 << BackgroundShift,
+ GreenBackground = 3 << BackgroundShift,
+ CyanBackground = 4 << BackgroundShift,
+ RedBackground = 5 << BackgroundShift,
+ PurpleBackground = 6 << BackgroundShift,
+ BrownBackground = 7 << BackgroundShift,
+ DefaultColor = 1 << SpecialShift
+ };
+
+ typedef QFlags<ColorCodeComponent> ColorCode;
+ typedef QHash<int, ColorCode> ColorMapping;
+
+ ColorOutput();
+ ~ColorOutput();
+
+ void setColorMapping(const ColorMapping &cMapping);
+ ColorMapping colorMapping() const;
+ void insertMapping(int colorID, const ColorCode colorCode);
+
+ void writeUncolored(const QString &message);
+ void write(const QString &message, int color = -1);
+ QString colorify(const QString &message, int color = -1) const;
+
+ private:
+ ColorOutputPrivate *d;
+ Q_DISABLE_COPY(ColorOutput)
+ };
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QPatternist::ColorOutput::ColorCode)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qdeviceresourceloader_p.h b/src/xmlpatterns/api/qdeviceresourceloader_p.h
new file mode 100644
index 0000000..fbea0a7
--- /dev/null
+++ b/src/xmlpatterns/api/qdeviceresourceloader_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QPatternist_DeviceResourceLoader_p_H
+#define QPatternist_DeviceResourceLoader_p_H
+
+template<typename T> class QSet;
+class QUrl;
+
+#include "qresourceloader_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for resource loaders that manage device variables.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @since 4.5
+ */
+ class DeviceResourceLoader : public ResourceLoader
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<DeviceResourceLoader> Ptr;
+ /**
+ * @short Returns the URIs for device variables that this
+ * ResourceLoader has loaded.
+ *
+ * The returned set may be empty.
+ */
+ virtual QSet<QUrl> deviceURIs() const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qiodevicedelegate.cpp b/src/xmlpatterns/api/qiodevicedelegate.cpp
new file mode 100644
index 0000000..ebd6e41
--- /dev/null
+++ b/src/xmlpatterns/api/qiodevicedelegate.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDebug>
+
+#include "qpatternistlocale_p.h"
+
+#include "qiodevicedelegate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QIODeviceDelegate::QIODeviceDelegate(QIODevice *const source) : m_source(source)
+{
+ Q_ASSERT(m_source);
+
+ connect(source, SIGNAL(aboutToClose()), SIGNAL(aboutToClose()));
+ connect(source, SIGNAL(bytesWritten(qint64)), SIGNAL(bytesWritten(qint64)));
+ connect(source, SIGNAL(readChannelFinished()), SIGNAL(readChannelFinished()));
+ connect(source, SIGNAL(readyRead()), SIGNAL(readyRead()));
+
+ /* According to Thiago these two signals are very similar, but QtNetworkAccess uses finished()
+ * instead for a minor but significant reason. */
+ connect(source, SIGNAL(readChannelFinished()), SIGNAL(finished()));
+
+ /* For instance QFile emits no signals, so how do we know if the device has all data available
+ * and it therefore is safe and correct to emit finished()? isSequential() tells us whether it's
+ * not random access, and whether it's safe to emit finished(). */
+ if(m_source->isSequential())
+ QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
+ else
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+
+ setOpenMode(QIODevice::ReadOnly);
+
+ /* Set up the timeout timer. */
+ connect(&m_timeout, SIGNAL(timeout()), SLOT(networkTimeout()));
+
+ m_timeout.setSingleShot(true);
+ m_timeout.start(Timeout);
+}
+
+void QIODeviceDelegate::networkTimeout()
+{
+ setErrorString(QtXmlPatterns::tr("Network timeout."));
+ error(QNetworkReply::TimeoutError);
+}
+
+void QIODeviceDelegate::abort()
+{
+ /* Do nothing, just to please QNetworkReply's pure virtual. */
+}
+
+bool QIODeviceDelegate::atEnd() const
+{
+ return m_source->atEnd();
+}
+
+qint64 QIODeviceDelegate::bytesAvailable() const
+{
+ return m_source->bytesAvailable();
+}
+
+qint64 QIODeviceDelegate::bytesToWrite() const
+{
+ return m_source->bytesToWrite();
+}
+
+bool QIODeviceDelegate::canReadLine() const
+{
+ return m_source->canReadLine();
+}
+
+void QIODeviceDelegate::close()
+{
+ return m_source->close();
+}
+
+bool QIODeviceDelegate::isSequential() const
+{
+ return m_source->isSequential();
+}
+
+bool QIODeviceDelegate::open(OpenMode mode)
+{
+ const bool success = m_source->open(mode);
+ setOpenMode(m_source->openMode());
+ return success;
+}
+
+qint64 QIODeviceDelegate::pos() const
+{
+ return m_source->pos();
+}
+
+bool QIODeviceDelegate::reset()
+{
+ return m_source->reset();
+}
+
+bool QIODeviceDelegate::seek(qint64 pos)
+{
+ return m_source->seek(pos);
+}
+
+qint64 QIODeviceDelegate::size() const
+{
+ return m_source->size();
+}
+
+bool QIODeviceDelegate::waitForBytesWritten(int msecs)
+{
+ return m_source->waitForBytesWritten(msecs);
+}
+
+bool QIODeviceDelegate::waitForReadyRead(int msecs)
+{
+ return m_source->waitForReadyRead(msecs);
+}
+
+qint64 QIODeviceDelegate::readData(char *data, qint64 maxSize)
+{
+ return m_source->read(data, maxSize);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qiodevicedelegate_p.h b/src/xmlpatterns/api/qiodevicedelegate_p.h
new file mode 100644
index 0000000..456048e
--- /dev/null
+++ b/src/xmlpatterns/api/qiodevicedelegate_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QIODEVICEDELEGATE_P_H
+#define QIODEVICEDELEGATE_P_H
+
+#include <QtCore/QTimer>
+#include <QtNetwork/QNetworkReply>
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * This is read-only currently.
+ */
+ class QIODeviceDelegate : public QNetworkReply
+ {
+ Q_OBJECT
+ public:
+ QIODeviceDelegate(QIODevice *const source);
+
+ virtual void abort();
+
+ virtual bool atEnd() const;
+ virtual qint64 bytesAvailable() const;
+ virtual qint64 bytesToWrite() const;
+ virtual bool canReadLine() const;
+ virtual void close();
+ virtual bool isSequential() const;
+ virtual bool open(OpenMode mode);
+ virtual qint64 pos() const;
+ virtual bool reset();
+ virtual bool seek(qint64 pos);
+ virtual qint64 size() const;
+ virtual bool waitForBytesWritten(int msecs);
+ virtual bool waitForReadyRead(int msecs);
+
+ protected:
+ virtual qint64 readData(char *data, qint64 maxSize);
+
+ private Q_SLOTS:
+ void networkTimeout();
+ private:
+ enum
+ {
+ /**
+ * 20 seconds expressed in milliseconds.
+ */
+ Timeout = 20000
+ };
+
+ QIODevice *const m_source;
+ QTimer m_timeout;
+ };
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/xmlpatterns/api/qnetworkaccessdelegator.cpp b/src/xmlpatterns/api/qnetworkaccessdelegator.cpp
new file mode 100644
index 0000000..05c4b8e
--- /dev/null
+++ b/src/xmlpatterns/api/qnetworkaccessdelegator.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include <QNetworkAccessManager>
+
+#include "qnetworkaccessdelegator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NetworkAccessDelegator::NetworkAccessDelegator(QNetworkAccessManager *const genericManager,
+ QNetworkAccessManager *const variableURIManager) : m_genericManager(genericManager)
+ , m_variableURIManager(variableURIManager)
+{
+}
+
+QNetworkAccessManager *NetworkAccessDelegator::managerFor(const QUrl &uri)
+{
+ /* Unfortunately we have to do it this way, QUrl::isParentOf() doesn't
+ * understand URI schemes like this one. */
+ const QString requestedUrl(uri.toString());
+
+ /* On the topic of timeouts:
+ *
+ * Currently the schemes QNetworkAccessManager handles should/will do
+ * timeouts for 4.4, but we need to do timeouts for our own. */
+ if(requestedUrl.startsWith(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:")))
+ return m_variableURIManager;
+ else
+ {
+ if(!m_genericManager)
+ m_genericManager = new QNetworkAccessManager(this);
+
+ return m_genericManager;
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qnetworkaccessdelegator_p.h b/src/xmlpatterns/api/qnetworkaccessdelegator_p.h
new file mode 100644
index 0000000..10c229a
--- /dev/null
+++ b/src/xmlpatterns/api/qnetworkaccessdelegator_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QNETWORKACCESSDELEGATOR_P_H
+#define QNETWORKACCESSDELEGATOR_P_H
+
+#include <QObject>
+#include <QPointer>
+#include <QSharedData>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+class QNetworkAccessManager;
+class QUrl;
+
+namespace QPatternist
+{
+ /**
+ * @short A value based class that hands out QNetworkAccessManager
+ * appropriately for variable bindings.
+ *
+ * NetworkAccessDelegator is an indirection mechanism which takes care of
+ * the fact that QIODevice instances are injected into the data model by
+ * having them represented using a URI. managerFor() returns appropriately
+ * the right network access manager depending on whether the URI refers to
+ * a variable, or to something else.
+ *
+ * The constructor take a pointer to two NetworkAccessDelegator instances.
+ * First is a generic one, the second is the one which handles variable
+ * bindings. managerFor() then returns the appropriate one depending on the
+ * URI.
+ *
+ * @since 4.5
+ * @see AccelTreeResourceLoader::load()
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT NetworkAccessDelegator : public QObject
+ , public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NetworkAccessDelegator> Ptr;
+ NetworkAccessDelegator(QNetworkAccessManager *const genericManager,
+ QNetworkAccessManager *const variableURIManager);
+
+ QNetworkAccessManager *managerFor(const QUrl &uri);
+
+ QPointer<QNetworkAccessManager> m_genericManager;
+ QPointer<QNetworkAccessManager> m_variableURIManager;
+ private:
+ Q_DISABLE_COPY(NetworkAccessDelegator)
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qpullbridge.cpp b/src/xmlpatterns/api/qpullbridge.cpp
new file mode 100644
index 0000000..80dac38
--- /dev/null
+++ b/src/xmlpatterns/api/qpullbridge.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QVariant>
+
+#include "qabstractxmlnodemodel_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qitem_p.h"
+#include "qxmlname.h"
+#include "qxmlquery_p.h"
+
+#include "qpullbridge_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/*!
+ \brief Bridges a QPatternist::SequenceIterator to QAbstractXmlPullProvider.
+ \class QPatternist::PullBridge
+ \internal
+ \reentrant
+ \ingroup xml-tools
+
+ The approach of this class is rather straight forward since QPatternist::SequenceIterator
+ and QAbstractXmlPullProvider are conceptually similar. While QPatternist::SequenceIterator only
+ delivers top level items(since it's not an event stream, it's a list of items), PullBridge
+ needs to recursively iterate the children of nodes too, which is achieved through the
+ stack m_iterators.
+ */
+
+AbstractXmlPullProvider::Event PullBridge::next()
+{
+ m_index = m_iterators.top().second->next();
+
+ if(!m_index.isNull())
+ {
+ Item item(m_index);
+
+ if(item && item.isAtomicValue())
+ m_current = AtomicValue;
+ else
+ {
+ Q_ASSERT(item.isNode());
+
+ switch(m_index.kind())
+ {
+ case QXmlNodeModelIndex::Attribute:
+ {
+ m_current = Attribute;
+ break;
+ }
+ case QXmlNodeModelIndex::Comment:
+ {
+ m_current = Comment;
+ break;
+ }
+ case QXmlNodeModelIndex::Element:
+ {
+ m_iterators.push(qMakePair(StartElement, m_index.iterate(QXmlNodeModelIndex::AxisChild)));
+ m_current = StartElement;
+ break;
+ }
+ case QXmlNodeModelIndex::Document:
+ {
+ m_iterators.push(qMakePair(StartDocument, m_index.iterate(QXmlNodeModelIndex::AxisChild)));
+ m_current = StartDocument;
+ break;
+ }
+ case QXmlNodeModelIndex::Namespace:
+ {
+ m_current = Namespace;
+ break;
+ }
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ {
+ m_current = ProcessingInstruction;
+ break;
+ }
+ case QXmlNodeModelIndex::Text:
+ {
+ m_current = Text;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(m_iterators.isEmpty())
+ m_current = EndOfInput;
+ else
+ {
+ switch(m_iterators.top().first)
+ {
+ case StartOfInput:
+ {
+ m_current = EndOfInput;
+ break;
+ }
+ case StartElement:
+ {
+ m_current = EndElement;
+ m_iterators.pop();
+ break;
+ }
+ case StartDocument:
+ {
+ m_current = EndDocument;
+ m_iterators.pop();
+ break;
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Invalid value.");
+ m_current = EndOfInput;
+ }
+ }
+ }
+
+ }
+
+ return m_current;
+}
+
+AbstractXmlPullProvider::Event PullBridge::current() const
+{
+ return m_current;
+}
+
+QXmlNodeModelIndex PullBridge::index() const
+{
+ return m_index;
+}
+
+QSourceLocation PullBridge::sourceLocation() const
+{
+ return m_index.model()->sourceLocation(m_index);
+}
+
+QXmlName PullBridge::name() const
+{
+ return m_index.name();
+}
+
+QVariant PullBridge::atomicValue() const
+{
+ return QVariant();
+}
+
+QString PullBridge::stringValue() const
+{
+ return QString();
+}
+
+QHash<QXmlName, QString> PullBridge::attributes()
+{
+ Q_ASSERT(m_current == StartElement);
+
+ QHash<QXmlName, QString> attributes;
+
+ QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute);
+ QXmlNodeModelIndex index = it->next();
+ while (!index.isNull()) {
+ const Item attribute(index);
+ attributes.insert(index.name(), index.stringValue());
+
+ index = it->next();
+ }
+
+ return attributes;
+}
+
+QHash<QXmlName, QXmlItem> PullBridge::attributeItems()
+{
+ Q_ASSERT(m_current == StartElement);
+
+ QHash<QXmlName, QXmlItem> attributes;
+
+ QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute);
+ QXmlNodeModelIndex index = it->next();
+ while (!index.isNull()) {
+ const Item attribute(index);
+ attributes.insert(index.name(), QXmlItem(index));
+
+ index = it->next();
+ }
+
+ return attributes;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qpullbridge_p.h b/src/xmlpatterns/api/qpullbridge_p.h
new file mode 100644
index 0000000..1553a3e
--- /dev/null
+++ b/src/xmlpatterns/api/qpullbridge_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_PULLBRIDGE_P_H
+#define PATTERNIST_PULLBRIDGE_P_H
+
+#include <QtCore/QPair>
+#include <QtCore/QStack>
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qabstractxmlpullprovider_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class PullBridge : public AbstractXmlPullProvider
+ {
+ public:
+ inline PullBridge(const QXmlNodeModelIndex::Iterator::Ptr &it) : m_current(StartOfInput)
+ {
+ Q_ASSERT(it);
+ m_iterators.push(qMakePair(StartOfInput, it));
+ }
+
+ virtual Event next();
+ virtual Event current() const;
+ virtual QXmlName name() const;
+ /**
+ * Returns always an empty QVariant.
+ */
+ virtual QVariant atomicValue() const;
+ virtual QString stringValue() const;
+ virtual QHash<QXmlName, QString> attributes();
+ virtual QHash<QXmlName, QXmlItem> attributeItems();
+
+ QXmlNodeModelIndex index() const;
+ QSourceLocation sourceLocation() const;
+
+ private:
+ typedef QStack<QPair<Event, QXmlNodeModelIndex::Iterator::Ptr> > IteratorStack;
+ IteratorStack m_iterators;
+ QXmlNodeModelIndex m_index;
+ Event m_current;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qreferencecountedvalue_p.h b/src/xmlpatterns/api/qreferencecountedvalue_p.h
new file mode 100644
index 0000000..679660c
--- /dev/null
+++ b/src/xmlpatterns/api/qreferencecountedvalue_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QPatternist_ReferenceCountedValue_p_h
+#define QPatternist_ReferenceCountedValue_p_h
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+/*!
+ \class ReferenceCountedValue
+ \internal
+ \since 4.4
+ \brief A template class that reference counts a value.
+
+ This class is useful when an instance needs to have ownership semantics
+ as if it was value based. A typical examples is a QObject pointer, which
+ doesn't have a single owner.
+
+ This is achieved through storing a copy of the object as
+ a member inside ReferenceCountedValue, which never is copied. It will
+ stay in scope until the last reference to the ReferenceCountedValue instance
+ is removed, and subsequently ReferenceCountedValue is deleted and hence also
+ the contained value. One should use ReferenceCountedValue by passing around
+ copies of Ptr, which is a typedef for the QExplicitlySharedDataPointer
+ smart pointer.
+*/
+ template<typename T>
+ class ReferenceCountedValue : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ReferenceCountedValue<T> > Ptr;
+
+ inline ReferenceCountedValue(T *const v) : value(v)
+ {
+ }
+
+ inline ~ReferenceCountedValue()
+ {
+ delete value;
+ }
+
+ T *const value;
+ private:
+ /*!
+ Disabled, no implementation provided.
+ */
+ inline ReferenceCountedValue();
+ Q_DISABLE_COPY(ReferenceCountedValue)
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qresourcedelegator.cpp b/src/xmlpatterns/api/qresourcedelegator.cpp
new file mode 100644
index 0000000..cb78666
--- /dev/null
+++ b/src/xmlpatterns/api/qresourcedelegator.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qresourcedelegator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool ResourceDelegator::isUnparsedTextAvailable(const QUrl &uri,
+ const QString &encoding)
+{
+ return m_parentLoader->isUnparsedTextAvailable(uri, encoding);
+}
+
+ItemType::Ptr ResourceDelegator::announceUnparsedText(const QUrl &uri)
+{
+ return m_parentLoader->announceUnparsedText(uri);
+}
+
+Item ResourceDelegator::openUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where)
+{
+ return m_parentLoader->openUnparsedText(uri, encoding, context, where);
+}
+
+Item ResourceDelegator::openDocument(const QUrl &uri,
+ const ReportContext::Ptr &context)
+{
+ if(m_needsOverride.contains(uri))
+ return m_forDeviceLoader->openDocument(uri, context);
+ else
+ return m_parentLoader->openDocument(uri, context);
+}
+
+SequenceType::Ptr ResourceDelegator::announceDocument(const QUrl &uri, const Usage usageHint)
+{
+ return m_parentLoader->announceDocument(uri, usageHint);
+}
+
+bool ResourceDelegator::isDocumentAvailable(const QUrl &uri)
+{
+ return m_parentLoader->isDocumentAvailable(uri);
+}
+
+Item::Iterator::Ptr ResourceDelegator::openCollection(const QUrl &uri)
+{
+ return m_parentLoader->openCollection(uri);
+}
+
+SequenceType::Ptr ResourceDelegator::announceCollection(const QUrl &uri)
+{
+ return m_parentLoader->announceCollection(uri);
+}
+
+QSet<QUrl> ResourceDelegator::deviceURIs() const
+{
+ QSet<QUrl> uris(m_needsOverride);
+ uris |= m_forDeviceLoader->deviceURIs();
+ return uris;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qresourcedelegator_p.h b/src/xmlpatterns/api/qresourcedelegator_p.h
new file mode 100644
index 0000000..688a23f
--- /dev/null
+++ b/src/xmlpatterns/api/qresourcedelegator_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QPatternist_ResourceDelegator_p_H
+#define QPatternist_ResourceDelegator_p_H
+
+#include <QSet>
+#include <QUrl>
+
+#include "qdeviceresourceloader_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Delegates to another ResourceLoader, but in case a URI is in an
+ * exception list, it delegates to a different loader.
+ *
+ * This is used for handling device variables, since when a device variable
+ * is rebound, a resource loader needs to carry that binding, while the
+ * resource loader for the other query remains as is.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ResourceDelegator : public DeviceResourceLoader
+ {
+ public:
+ ResourceDelegator(const QSet<QUrl> &needsOverride,
+ const ResourceLoader::Ptr &parentLoader,
+ const ResourceLoader::Ptr &forDeviceLoader) : m_needsOverride(needsOverride)
+ , m_parentLoader(parentLoader)
+ , m_forDeviceLoader(forDeviceLoader)
+
+ {
+ Q_ASSERT(m_parentLoader);
+ }
+
+ virtual bool isUnparsedTextAvailable(const QUrl &uri,
+ const QString &encoding);
+ virtual ItemType::Ptr announceUnparsedText(const QUrl &uri);
+ virtual Item openUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where);
+ virtual Item openDocument(const QUrl &uri,
+ const ReportContext::Ptr &context);
+ virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint);
+ virtual bool isDocumentAvailable(const QUrl &uri);
+ virtual Item::Iterator::Ptr openCollection(const QUrl &uri);
+ virtual SequenceType::Ptr announceCollection(const QUrl &uri);
+
+ /**
+ * Returns the union of the deviceURIs() that ResourceDelegator's two
+ * resource loaders has.
+ */
+ virtual QSet<QUrl> deviceURIs() const;
+
+ private:
+ const QSet<QUrl> m_needsOverride;
+ const ResourceLoader::Ptr m_parentLoader;
+ const ResourceDelegator::Ptr m_forDeviceLoader;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qsimplexmlnodemodel.cpp b/src/xmlpatterns/api/qsimplexmlnodemodel.cpp
new file mode 100644
index 0000000..40f99e5
--- /dev/null
+++ b/src/xmlpatterns/api/qsimplexmlnodemodel.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+#include <QVector>
+#include <QXmlNamePool>
+
+#include "qabstractxmlnodemodel_p.h"
+#include "qemptyiterator_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qsequencemappingiterator_p.h"
+#include "qsimplexmlnodemodel.h"
+#include "qsingletoniterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+class QSimpleXmlNodeModelPrivate : public QAbstractXmlNodeModelPrivate
+{
+public:
+ QSimpleXmlNodeModelPrivate(const QXmlNamePool &np) : namePool(np)
+ {
+ }
+
+ mutable QXmlNamePool namePool;
+};
+
+/*!
+ \class QSimpleXmlNodeModel
+ \brief The QSimpleXmlNodeModel class is an implementation of QAbstractXmlNodeModel sufficient for many common cases.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ Subclassing QAbstractXmlNodeModel can be a significant task, because it
+ requires implementing several, complex member functions. QSimpleXmlNodeModel
+ provides default implementations of these member functions that are suitable
+ for a wide range of node models.
+
+ Subclasses of QSimpleXmlNodeModel must be thread-safe.
+ */
+
+/*!
+ Constructs a QSimpleXmlNodeModel for use with with the specified
+ \a namePool.
+ */
+QSimpleXmlNodeModel::QSimpleXmlNodeModel(const QXmlNamePool &namePool)
+ : QAbstractXmlNodeModel(new QSimpleXmlNodeModelPrivate(namePool))
+{
+}
+
+/*!
+ Destructor.
+ */
+QSimpleXmlNodeModel::~QSimpleXmlNodeModel()
+{
+}
+
+/*!
+ If \a node is an element or attribute, typedValue() is called, and
+ the return value converted to a string, as per XQuery's rules.
+
+ If \a node is another type of node, the empty string is returned.
+
+ If this function is overridden for comments or processing
+ instructions, it is important to remember to call it (for elements
+ and attributes having values not of type \c xs:string) to ensure that
+ the values are formatted according to XQuery.
+
+ */
+QString QSimpleXmlNodeModel::stringValue(const QXmlNodeModelIndex &node) const
+{
+ const QXmlNodeModelIndex::NodeKind k= kind(node);
+ if(k == QXmlNodeModelIndex::Element || k == QXmlNodeModelIndex::Attribute)
+ {
+ const QVariant &candidate = typedValue(node);
+ if(candidate.isNull())
+ return QString();
+ else
+ return AtomicValue::toXDM(candidate).stringValue();
+ }
+ else
+ return QString();
+}
+
+/*!
+ Returns the base URI for \a node. This is always the document
+ URI.
+
+ \sa documentUri()
+ */
+QUrl QSimpleXmlNodeModel::baseUri(const QXmlNodeModelIndex &node) const
+{
+ return documentUri(node);
+}
+
+/*!
+ Returns the name pool associated with this model. The
+ implementation of name() will use this name pool to create
+ names.
+ */
+QXmlNamePool &QSimpleXmlNodeModel::namePool() const
+{
+ Q_D(const QSimpleXmlNodeModel);
+
+ return d->namePool;
+}
+
+/*!
+ Always returns an empty QVector. This signals that no namespace
+ bindings are in scope for \a node.
+ */
+QVector<QXmlName> QSimpleXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &node) const
+{
+ Q_UNUSED(node);
+ return QVector<QXmlName>();
+}
+
+/*!
+ Always returns a default constructed QXmlNodeModelIndex instance,
+ regardless of \a id.
+
+ This effectively means the model has no elements that have an id.
+ */
+QXmlNodeModelIndex QSimpleXmlNodeModel::elementById(const QXmlName &id) const
+{
+ Q_UNUSED(id);
+ return QXmlNodeModelIndex();
+}
+
+/*!
+ Always returns an empty vector, regardless of \a idref.
+
+ This effectively means the model has no elements or attributes of
+ type \c IDREF.
+ */
+QVector<QXmlNodeModelIndex> QSimpleXmlNodeModel::nodesByIdref(const QXmlName &idref) const
+{
+ Q_UNUSED(idref);
+ return QVector<QXmlNodeModelIndex>();
+}
+
+QT_END_NAMESPACE
+
+
diff --git a/src/xmlpatterns/api/qsimplexmlnodemodel.h b/src/xmlpatterns/api/qsimplexmlnodemodel.h
new file mode 100644
index 0000000..cfbe360
--- /dev/null
+++ b/src/xmlpatterns/api/qsimplexmlnodemodel.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSIMPLEXMLNODEMODEL_H
+#define QSIMPLEXMLNODEMODEL_H
+
+#include <QtXmlPatterns/QAbstractXmlNodeModel>
+#include <QtXmlPatterns/QXmlQuery>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+template<typename T> class QExplicitlySharedDataPointer;
+class QSimpleXmlNodeModelPrivate;
+class Q_XMLPATTERNS_EXPORT QSimpleXmlNodeModel : public QAbstractXmlNodeModel
+{
+public:
+ QSimpleXmlNodeModel(const QXmlNamePool &namePool);
+ virtual ~QSimpleXmlNodeModel();
+
+ virtual QUrl baseUri(const QXmlNodeModelIndex &node) const;
+ QXmlNamePool &namePool() const;
+ virtual QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex&) const;
+ virtual QString stringValue(const QXmlNodeModelIndex &node) const;
+ virtual QXmlNodeModelIndex elementById(const QXmlName &id) const;
+ virtual QVector<QXmlNodeModelIndex> nodesByIdref(const QXmlName &idref) const;
+
+private:
+ Q_DECLARE_PRIVATE(QSimpleXmlNodeModel)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qsourcelocation.cpp b/src/xmlpatterns/api/qsourcelocation.cpp
new file mode 100644
index 0000000..392d84c
--- /dev/null
+++ b/src/xmlpatterns/api/qsourcelocation.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdebug_p.h"
+
+#include "qsourcelocation.h"
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QSourceLocation
+ \reentrant
+ \since 4.4
+ \brief The QSourceLocation class identifies a location in a resource by URI, line, and column.
+ \ingroup xml-tools
+
+ QSourceLocation is a simple value based class that has three
+ properties, uri(), line(), and column(), that, taken together,
+ identify a certain point in a resource, e.g., a file or an in-memory
+ document.
+
+ line() and column() refer to character counts (not byte counts), and
+ they both start from 1, as opposed to 0.
+ */
+
+/*!
+ Construct a QSourceLocation that doesn't identify anything at all.
+
+ For a default constructed QSourceLocation(), isNull() returns \c true.
+ */
+QSourceLocation::QSourceLocation() : m_line(-1), m_column(-1)
+{
+}
+
+/*!
+ Constructs a QSourceLocation that is a copy of \a other.
+ */
+QSourceLocation::QSourceLocation(const QSourceLocation &other)
+ : m_line(other.m_line), m_column(other.m_column), m_uri(other.m_uri)
+{
+}
+
+/*!
+ Constructs a QSourceLocation with URI \a u, line \a l and column \a c.
+ */
+QSourceLocation::QSourceLocation(const QUrl &u, int l, int c)
+ : m_line(l), m_column(c), m_uri(u)
+{
+}
+
+/*!
+ Destructor.
+ */
+QSourceLocation::~QSourceLocation()
+{
+}
+
+/*!
+ Returns true if this QSourceLocation is identical to \a other.
+
+ Two QSourceLocation instances are equal if their uri(), line() and
+ column() are equal.
+
+ QSourceLocation instances for which isNull() returns true are
+ considered equal.
+ */
+bool QSourceLocation::operator==(const QSourceLocation &other) const
+{
+ return m_line == other.m_line
+ && m_column == other.m_column
+ && m_uri == other.m_uri;
+}
+
+/*!
+ Returns the opposite of applying operator==() for this QXmlName
+ and \a other.
+ */
+bool QSourceLocation::operator!=(const QSourceLocation &other) const
+{
+ return operator==(other);
+}
+
+/*!
+ Assigns this QSourceLocation instance to \a other.
+ */
+QSourceLocation &QSourceLocation::operator=(const QSourceLocation &other)
+{
+ if(this != &other)
+ {
+ m_line = other.m_line;
+ m_column = other.m_column;
+ m_uri = other.m_uri;
+ }
+
+ return *this;
+}
+
+/*!
+ Returns the current column number. The column number refers to the
+ count of characters, not bytes. The first column is column 1, not 0.
+ The default value is -1, indicating the column number is unknown.
+ */
+qint64 QSourceLocation::column() const
+{
+ return m_column;
+}
+
+/*!
+ Sets the column number to \a newColumn. 0 is an invalid column
+ number. The first column number is 1.
+ */
+void QSourceLocation::setColumn(qint64 newColumn)
+{
+ Q_ASSERT_X(newColumn != 0, Q_FUNC_INFO,
+ "0 is an invalid column number. The first column number is 1.");
+ m_column = newColumn;
+}
+
+/*!
+ Returns the current line number. The first line number is 1, not 0.
+ The default value is -1, indicating the line number is unknown.
+ */
+qint64 QSourceLocation::line() const
+{
+ return m_line;
+}
+
+/*!
+ Sets the line number to \a newLine. 0 is an invalid line
+ number. The first line number is 1.
+ */
+void QSourceLocation::setLine(qint64 newLine)
+{
+ m_line = newLine;
+}
+
+/*!
+ Returns the resource that this QSourceLocation refers to. For
+ example, the resource could be a file in the local file system,
+ if the URI scheme is \c file.
+ */
+QUrl QSourceLocation::uri() const
+{
+ return m_uri;
+}
+
+/*!
+ Sets the URI to \a newUri.
+ */
+void QSourceLocation::setUri(const QUrl &newUri)
+{
+ m_uri = newUri;
+}
+
+/*!
+ \relates QSourceLocation
+ \since 4.4
+
+ Prints \a sourceLocation to the debug stream \a debug.
+ */
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QSourceLocation &sourceLocation)
+{
+ debug << "QSourceLocation("
+ << sourceLocation.uri()
+ << ", line:"
+ << sourceLocation.line()
+ << ", column:"
+ << sourceLocation.column()
+ << ')';
+ return debug;
+}
+#endif
+
+/*!
+ Returns \c true if this QSourceLocation doesn't identify anything.
+
+ For a default constructed QSourceLocation, this function returns \c
+ true. The same applies for any other QSourceLocation whose uri() is
+ invalid.
+ */
+bool QSourceLocation::isNull() const
+{
+ return !m_uri.isValid();
+}
+
+/*!
+ \since 4.4
+
+ Computes a hash key for the QSourceLocation \a location.
+
+ \relates QSourceLocation
+ */
+uint qHash(const QSourceLocation &location)
+{
+ /* Not the world's best hash function exactly. */
+ return qHash(location.uri().toString()) + location.line() + location.column();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qsourcelocation.h b/src/xmlpatterns/api/qsourcelocation.h
new file mode 100644
index 0000000..80184fd
--- /dev/null
+++ b/src/xmlpatterns/api/qsourcelocation.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOURCELOCATION_H
+#define QSOURCELOCATION_H
+
+#include <QtCore/QMetaType>
+#include <QtCore/QUrl>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QSourceLocationPrivate;
+
+class Q_XMLPATTERNS_EXPORT QSourceLocation
+{
+public:
+ QSourceLocation();
+ QSourceLocation(const QSourceLocation &other);
+ QSourceLocation(const QUrl &uri, int line = -1, int column = -1);
+ ~QSourceLocation();
+ QSourceLocation &operator=(const QSourceLocation &other);
+ bool operator==(const QSourceLocation &other) const;
+ bool operator!=(const QSourceLocation &other) const;
+
+ qint64 column() const;
+ void setColumn(qint64 newColumn);
+
+ qint64 line() const;
+ void setLine(qint64 newLine);
+
+ QUrl uri() const;
+ void setUri(const QUrl &newUri);
+ bool isNull() const;
+
+private:
+ union
+ {
+ qint64 m_line;
+ QSourceLocationPrivate *m_ptr;
+ };
+ qint64 m_column;
+ QUrl m_uri;
+};
+
+Q_XMLPATTERNS_EXPORT uint qHash(const QSourceLocation &location);
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_XMLPATTERNS_EXPORT QDebug operator<<(QDebug debug, const QSourceLocation &sourceLocation);
+#endif
+
+Q_DECLARE_TYPEINFO(QSourceLocation, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QSourceLocation) /* This macro must appear after QT_END_NAMESPACE. */
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/quriloader.cpp b/src/xmlpatterns/api/quriloader.cpp
new file mode 100644
index 0000000..b8cb104
--- /dev/null
+++ b/src/xmlpatterns/api/quriloader.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtNetwork/QNetworkRequest>
+#include <QtNetwork/QNetworkReply>
+
+#include "qiodevicedelegate_p.h"
+#include "quriloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+URILoader::URILoader(QObject *const parent,
+ const NamePool::Ptr &np,
+ const VariableLoader::Ptr &l) : QNetworkAccessManager(parent)
+ , m_variableNS(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:"))
+ , m_namePool(np)
+ , m_variableLoader(l)
+{
+ Q_ASSERT(m_variableLoader);
+}
+
+QNetworkReply *URILoader::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData)
+{
+ const QString requestedUrl(req.url().toString());
+
+ /* We got a QIODevice variable. */
+ const QString name(requestedUrl.right(requestedUrl.length() - m_variableNS.length()));
+
+ const QVariant variant(m_variableLoader->valueFor(m_namePool->allocateQName(QString(), name, QString())));
+
+ if(!variant.isNull() && variant.userType() == qMetaTypeId<QIODevice *>())
+ return new QIODeviceDelegate(qvariant_cast<QIODevice *>(variant));
+ else
+ {
+ /* If we're entering this code path, the variable URI identified a variable
+ * which we don't have, which means we either have a bug, or the user had
+ * crafted an invalid URI manually. */
+
+ return QNetworkAccessManager::createRequest(op, req, outgoingData);
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/quriloader_p.h b/src/xmlpatterns/api/quriloader_p.h
new file mode 100644
index 0000000..eaaca5f
--- /dev/null
+++ b/src/xmlpatterns/api/quriloader_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QURILOADER_P_H
+#define QURILOADER_P_H
+
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtXmlPatterns/QXmlName>
+
+#include "qnamepool_p.h"
+#include "qvariableloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class URILoader : public QNetworkAccessManager
+ {
+ public:
+ URILoader(QObject *const parent,
+ const NamePool::Ptr &np,
+ const VariableLoader::Ptr &variableLoader);
+
+ virtual QNetworkReply *createRequest(Operation op,
+ const QNetworkRequest & req,
+ QIODevice *outgoingData = 0);
+
+ private:
+ const QString m_variableNS;
+ const NamePool::Ptr m_namePool;
+ const VariableLoader::Ptr m_variableLoader;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/xmlpatterns/api/qvariableloader.cpp b/src/xmlpatterns/api/qvariableloader.cpp
new file mode 100644
index 0000000..9909508
--- /dev/null
+++ b/src/xmlpatterns/api/qvariableloader.cpp
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QVariant>
+#include <QStringList>
+
+#include "qanyuri_p.h"
+#include "qatomicstring_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qinteger_p.h"
+#include "qitem_p.h"
+#include "qsequencetype_p.h"
+#include "qvariableloader_p.h"
+#include "qxmlquery_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ class VariantListIterator : public ListIteratorPlatform<QVariant, Item, VariantListIterator>
+ {
+ public:
+ inline VariantListIterator(const QVariantList &list) : ListIteratorPlatform<QVariant, Item, VariantListIterator>(list)
+ {
+ }
+
+ private:
+ friend class ListIteratorPlatform<QVariant, Item, VariantListIterator>;
+
+ inline Item inputToOutputItem(const QVariant &inputType) const
+ {
+ return AtomicValue::toXDM(inputType);
+ }
+ };
+
+ class StringListIterator : public ListIteratorPlatform<QString, Item, StringListIterator>
+ {
+ public:
+ inline StringListIterator(const QStringList &list) : ListIteratorPlatform<QString, Item, StringListIterator>(list)
+ {
+ }
+
+ private:
+ friend class ListIteratorPlatform<QString, Item, StringListIterator>;
+
+ static inline Item inputToOutputItem(const QString &inputType)
+ {
+ return AtomicString::fromValue(inputType);
+ }
+ };
+
+ /**
+ * Takes two DynamicContext instances, and redirects the storage of temporary trees
+ * to one of them.
+ *
+ * @since 4.5
+ */
+ class TemporaryTreesRedirectingContext : public DelegatingDynamicContext
+ {
+ public:
+ TemporaryTreesRedirectingContext(const DynamicContext::Ptr &other,
+ const DynamicContext::Ptr &modelStorage) : DelegatingDynamicContext(other)
+ , m_modelStorage(modelStorage)
+ {
+ Q_ASSERT(m_modelStorage);
+ }
+
+ virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nodeModel)
+ {
+ m_modelStorage->addNodeModel(nodeModel);
+ }
+
+ private:
+ const DynamicContext::Ptr m_modelStorage;
+ };
+}
+
+using namespace QPatternist;
+
+SequenceType::Ptr VariableLoader::announceExternalVariable(const QXmlName name,
+ const SequenceType::Ptr &declaredType)
+{
+ Q_UNUSED(declaredType);
+ const QVariant &variant = m_bindingHash.value(name);
+
+
+ if(variant.isNull())
+ return SequenceType::Ptr();
+ else if(variant.userType() == qMetaTypeId<QIODevice *>())
+ return CommonSequenceTypes::ExactlyOneAnyURI;
+ else if(variant.userType() == qMetaTypeId<QXmlQuery>())
+ {
+ const QXmlQuery variableQuery(qvariant_cast<QXmlQuery>(variant));
+ return variableQuery.d->expression()->staticType();
+ }
+ else
+ {
+ return makeGenericSequenceType(AtomicValue::qtToXDMType(qvariant_cast<QXmlItem>(variant)),
+ Cardinality::exactlyOne());
+ }
+}
+
+Item::Iterator::Ptr VariableLoader::evaluateSequence(const QXmlName name,
+ const DynamicContext::Ptr &context)
+{
+
+ const QVariant &variant = m_bindingHash.value(name);
+ Q_ASSERT_X(!variant.isNull(), Q_FUNC_INFO,
+ "We assume that we have a binding.");
+
+ /* Same code as in the default clause below. */
+ if(variant.userType() == qMetaTypeId<QIODevice *>())
+ return makeSingletonIterator(itemForName(name));
+ else if(variant.userType() == qMetaTypeId<QXmlQuery>())
+ {
+ const QXmlQuery variableQuery(qvariant_cast<QXmlQuery>(variant));
+
+ return variableQuery.d->expression()->evaluateSequence(DynamicContext::Ptr(new TemporaryTreesRedirectingContext(variableQuery.d->dynamicContext(), context)));
+ }
+
+ const QVariant v(qvariant_cast<QXmlItem>(variant).toAtomicValue());
+
+ switch(v.type())
+ {
+ case QVariant::StringList:
+ return Item::Iterator::Ptr(new StringListIterator(v.toStringList()));
+ case QVariant::List:
+ return Item::Iterator::Ptr(new VariantListIterator(v.toList()));
+ default:
+ return makeSingletonIterator(itemForName(name));
+ }
+}
+
+Item VariableLoader::itemForName(const QXmlName &name) const
+{
+ const QVariant &variant = m_bindingHash.value(name);
+
+ if(variant.userType() == qMetaTypeId<QIODevice *>())
+ return Item(AnyURI::fromValue(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + m_namePool->stringForLocalName(name.localName())));
+
+ const QXmlItem item(qvariant_cast<QXmlItem>(variant));
+
+ if(item.isNode())
+ return Item::fromPublic(item);
+ else
+ {
+ const QVariant atomicValue(item.toAtomicValue());
+ /* If the atomicValue is null it means it doesn't exist in m_bindingHash, and therefore it must
+ * be a QIODevice, since Patternist guarantees to only ask for variables that announceExternalVariable()
+ * has accepted. */
+ if(atomicValue.isNull())
+ return Item(AnyURI::fromValue(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + m_namePool->stringForLocalName(name.localName())));
+ else
+ return AtomicValue::toXDM(atomicValue);
+ }
+}
+
+Item VariableLoader::evaluateSingleton(const QXmlName name,
+ const DynamicContext::Ptr &)
+{
+ return itemForName(name);
+}
+
+bool VariableLoader::isSameType(const QVariant &v1,
+ const QVariant &v2) const
+{
+ /* Are both of type QIODevice *? */
+ if(v1.userType() == qMetaTypeId<QIODevice *>() && v1.userType() == v2.userType())
+ return true;
+
+ /* Ok, we have two QXmlItems. */
+ const QXmlItem i1(qvariant_cast<QXmlItem>(v1));
+ const QXmlItem i2(qvariant_cast<QXmlItem>(v2));
+
+ if(i1.isNode())
+ {
+ Q_ASSERT(false);
+ return false;
+ }
+ else if(i2.isAtomicValue())
+ return i1.toAtomicValue().type() == i2.toAtomicValue().type();
+ else
+ {
+ /* One is an atomic, the other is a node or they are null. */
+ return false;
+ }
+}
+
+void VariableLoader::removeBinding(const QXmlName &name)
+{
+ m_bindingHash.remove(name);
+}
+
+bool VariableLoader::hasBinding(const QXmlName &name) const
+{
+ return m_bindingHash.contains(name)
+ || (m_previousLoader && m_previousLoader->hasBinding(name));
+}
+
+QVariant VariableLoader::valueFor(const QXmlName &name) const
+{
+ if(m_bindingHash.contains(name))
+ return m_bindingHash.value(name);
+ else if(m_previousLoader)
+ return m_previousLoader->valueFor(name);
+ else
+ return QVariant();
+}
+
+void VariableLoader::addBinding(const QXmlName &name,
+ const QVariant &value)
+{
+ m_bindingHash.insert(name, value);
+}
+
+bool VariableLoader::invalidationRequired(const QXmlName &name,
+ const QVariant &variant) const
+{
+ return hasBinding(name) && !isSameType(valueFor(name), variant);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qvariableloader_p.h b/src/xmlpatterns/api/qvariableloader_p.h
new file mode 100644
index 0000000..cf050cb
--- /dev/null
+++ b/src/xmlpatterns/api/qvariableloader_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_VARIABLELOADER_P_H
+#define PATTERNIST_VARIABLELOADER_P_H
+
+#include <QtCore/QSet>
+#include <QtXmlPatterns/QXmlQuery>
+#include <QtDebug>
+
+#include "qdynamiccontext_p.h"
+#include "qexternalvariableloader_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class VariableLoader : public ExternalVariableLoader
+ {
+ public:
+ typedef QHash<QXmlName, QVariant> BindingHash;
+ typedef QExplicitlySharedDataPointer<VariableLoader> Ptr;
+
+ inline VariableLoader(const NamePool::Ptr &np,
+ const VariableLoader::Ptr &previousLoader = VariableLoader::Ptr()) : m_namePool(np)
+ , m_previousLoader(previousLoader)
+
+ {
+ }
+
+ virtual QPatternist::SequenceType::Ptr announceExternalVariable(const QXmlName name,
+ const QPatternist::SequenceType::Ptr &declaredType);
+ virtual QPatternist::Item::Iterator::Ptr evaluateSequence(const QXmlName name,
+ const QPatternist::DynamicContext::Ptr &);
+
+ virtual QPatternist::Item evaluateSingleton(const QXmlName name,
+ const QPatternist::DynamicContext::Ptr &);
+
+ void removeBinding(const QXmlName &name);
+ bool hasBinding(const QXmlName &name) const;
+ QVariant valueFor(const QXmlName &name) const;
+ void addBinding(const QXmlName &name,
+ const QVariant &value);
+
+ bool isSameType(const QVariant &v1,
+ const QVariant &v2) const;
+
+ bool invalidationRequired(const QXmlName &name,
+ const QVariant &variant) const;
+
+ private:
+
+ inline QPatternist::Item itemForName(const QXmlName &name) const;
+
+ const NamePool::Ptr m_namePool;
+ VariableLoader::Ptr m_previousLoader;
+ BindingHash m_bindingHash;
+ };
+}
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QIODevice *)
+Q_DECLARE_METATYPE(QXmlQuery)
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlformatter.cpp b/src/xmlpatterns/api/qxmlformatter.cpp
new file mode 100644
index 0000000..0925fe5
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlformatter.cpp
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDebug>
+
+#include "qxmlformatter.h"
+#include "qxpathhelper_p.h"
+#include "qxmlserializer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+class QXmlFormatterPrivate : public QXmlSerializerPrivate
+{
+public:
+ inline QXmlFormatterPrivate(const QXmlQuery &q,
+ QIODevice *const outputDevice);
+
+ int indentationDepth;
+ int currentDepth;
+ QString characterBuffer;
+ QString indentString;
+
+ /**
+ * Whether we /have/ sent nodes like processing instructions and comments
+ * to QXmlSerializer.
+ */
+ QStack<bool> canIndent;
+};
+
+QXmlFormatterPrivate::QXmlFormatterPrivate(const QXmlQuery &query,
+ QIODevice *const outputDevice) : QXmlSerializerPrivate(query, outputDevice)
+ , indentationDepth(4)
+ , currentDepth(0)
+{
+ indentString.reserve(30);
+ indentString.resize(1);
+ indentString[0] = QLatin1Char('\n');
+ canIndent.push(false);
+}
+
+/*!
+ \class QXmlFormatter
+ \brief The QXmlFormatter class is an implementation of QXmlSerializer for transforming XQuery output into formatted XML.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ QXmlFormatter is a subclass of QXmlSerializer that formats the XML
+ output to make it easier for humans to read.
+
+ QXmlSerializer outputs XML without adding unnecessary whitespace.
+ In particular, it does not add \e {newlines} and indentation.
+ To make the XML output easier to read, QXmlFormatter adds \e{newlines}
+ and indentation by adding, removing, and modifying
+ \l{XQuery Sequence}{sequence nodes} that only consist of whitespace.
+ It also modifies whitespace in other places where it is not
+ significant; e.g., between attributes and in the document prologue.
+
+ For example, where the base class QXmlSerializer would
+ output this:
+
+ \quotefile doc/src/snippets/patternist/notIndented.xml
+
+ QXmlFormatter outputs this:
+
+ \quotefile doc/src/snippets/patternist/indented.xml
+
+ If you just want to serialize your XML in a human-readable
+ format, use QXmlFormatter as it is. The default indentation
+ level is 4 spaces, but you can set your own indentation value
+ setIndentationDepth().
+
+ The \e{newlines} and indentation added by QXmlFormatter are
+ suitable for common formats, such as XHTML, SVG, or Docbook,
+ where whitespace is not significant. However, if your XML will
+ be used as input where whitespace is significant, then you must
+ write your own subclass of QXmlSerializer or QAbstractXmlReceiver.
+
+ Note that using QXmlFormatter instead of QXmlSerializer will
+ increase computational overhead and document storage size due
+ to the insertion of whitespace.
+
+ Note also that the indentation style used by QXmlFormatter
+ remains loosely defined and may change in future versions of
+ Qt. If a specific indentation style is required then either
+ use the base class QXmlSerializer directly, or write your own
+ subclass of QXmlSerializer or QAbstractXmlReceiver.
+ Alternatively, you can subclass QXmlFormatter and reimplement
+ the callbacks there.
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp 0
+*/
+
+/*!
+ Constructs a formatter that uses the name pool and message
+ handler in \a query, and writes the result to \a outputDevice
+ as formatted XML.
+
+ \a outputDevice is passed directly to QXmlSerializer's constructor.
+
+ \sa QXmlSerializer
+ */
+QXmlFormatter::QXmlFormatter(const QXmlQuery &query,
+ QIODevice *outputDevice) : QXmlSerializer(new QXmlFormatterPrivate(query, outputDevice))
+{
+}
+
+/*!
+ \internal
+ */
+void QXmlFormatter::startFormattingContent()
+{
+ Q_D(QXmlFormatter);
+
+ if(QPatternist::XPathHelper::isWhitespaceOnly(d->characterBuffer))
+ {
+ if(d->canIndent.top())
+ QXmlSerializer::characters(QStringRef(&d->indentString));
+ }
+ else
+ {
+ if(!d->characterBuffer.isEmpty()) /* Significant data, we don't touch it. */
+ QXmlSerializer::characters(QStringRef(&d->characterBuffer));
+ }
+
+ d->characterBuffer.clear();
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::startElement(const QXmlName &name)
+{
+ Q_D(QXmlFormatter);
+ startFormattingContent();
+ ++d->currentDepth;
+ d->indentString.append(QString(d->indentationDepth, QLatin1Char(' ')));
+ d->canIndent.push(true);
+
+ QXmlSerializer::startElement(name);
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::endElement()
+{
+ Q_D(QXmlFormatter);
+ --d->currentDepth;
+ d->indentString.chop(d->indentationDepth);
+
+ if(!d->hasClosedElement.top().second)
+ d->canIndent.top() = false;
+
+ startFormattingContent();
+
+ d->canIndent.pop();
+ d->canIndent.top() = true;
+ QXmlSerializer::endElement();
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::attribute(const QXmlName &name,
+ const QStringRef &value)
+{
+ QXmlSerializer::attribute(name, value);
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::comment(const QString &value)
+{
+ Q_D(QXmlFormatter);
+ startFormattingContent();
+ QXmlSerializer::comment(value);
+ d->canIndent.top() = true;
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::characters(const QStringRef &value)
+{
+ Q_D(QXmlFormatter);
+ d->isPreviousAtomic = false;
+ d->characterBuffer += value.toString();
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::processingInstruction(const QXmlName &name,
+ const QString &value)
+{
+ Q_D(QXmlFormatter);
+ startFormattingContent();
+ QXmlSerializer::processingInstruction(name, value);
+ d->canIndent.top() = true;
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::atomicValue(const QVariant &value)
+{
+ Q_D(QXmlFormatter);
+ d->canIndent.top() = false;
+ QXmlSerializer::atomicValue(value);
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::startDocument()
+{
+ QXmlSerializer::startDocument();
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::endDocument()
+{
+ QXmlSerializer::endDocument();
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::startOfSequence()
+{
+ QXmlSerializer::startOfSequence();
+}
+
+/*!
+ \reimp
+ */
+void QXmlFormatter::endOfSequence()
+{
+ Q_D(QXmlFormatter);
+
+ /* Flush any buffered content. */
+ if(!d->characterBuffer.isEmpty())
+ QXmlSerializer::characters(QStringRef(&d->characterBuffer));
+
+ d->write('\n');
+ QXmlSerializer::endOfSequence();
+}
+
+/*!
+ \internal
+ */
+void QXmlFormatter::item(const QPatternist::Item &item)
+{
+ Q_D(QXmlFormatter);
+
+ if(item.isAtomicValue())
+ {
+ if(QPatternist::XPathHelper::isWhitespaceOnly(item.stringValue()))
+ return;
+ else
+ {
+ d->canIndent.top() = false;
+ startFormattingContent();
+ }
+ }
+
+ QXmlSerializer::item(item);
+}
+
+/*!
+ Returns the number of spaces QXmlFormatter will output for each
+ indentation level. The default is four.
+
+ \sa setIndentationDepth()
+ */
+int QXmlFormatter::indentationDepth() const
+{
+ Q_D(const QXmlFormatter);
+ return d->indentationDepth;
+}
+
+/*!
+ Sets \a depth to be the number of spaces QXmlFormatter will
+ output for level of indentation. The default is four.
+
+ \sa indentationDepth()
+ */
+void QXmlFormatter::setIndentationDepth(int depth)
+{
+ Q_D(QXmlFormatter);
+ d->indentationDepth = depth;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qxmlformatter.h b/src/xmlpatterns/api/qxmlformatter.h
new file mode 100644
index 0000000..8ad3aa2
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlformatter.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLFORMATTER_H
+#define QXMLFORMATTER_H
+
+#include <QtXmlPatterns/QXmlSerializer>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QIODevice;
+class QTextCodec;
+class QXmlQuery;
+class QXmlFormatterPrivate;
+
+class Q_XMLPATTERNS_EXPORT QXmlFormatter : public QXmlSerializer
+{
+public:
+ QXmlFormatter(const QXmlQuery &query,
+ QIODevice *outputDevice);
+
+ virtual void characters(const QStringRef &value);
+ virtual void comment(const QString &value);
+ virtual void startElement(const QXmlName &name);
+ virtual void endElement();
+
+ virtual void attribute(const QXmlName &name,
+ const QStringRef &value);
+ virtual void processingInstruction(const QXmlName &name,
+ const QString &value);
+ virtual void atomicValue(const QVariant &value);
+ virtual void startDocument();
+ virtual void endDocument();
+ virtual void startOfSequence();
+ virtual void endOfSequence();
+
+ int indentationDepth() const;
+ void setIndentationDepth(int depth);
+
+ /* The members below are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+ virtual void item(const QPatternist::Item &item);
+private:
+ inline void startFormattingContent();
+ Q_DECLARE_PRIVATE(QXmlFormatter)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlname.cpp b/src/xmlpatterns/api/qxmlname.cpp
new file mode 100644
index 0000000..8ff7411
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlname.cpp
@@ -0,0 +1,511 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * QXmlName is conceptually identical to QPatternist::QName. The
+ * difference is that the latter is elegant, powerful and fast.
+ *
+ * However, it is too powerful and too open and not at all designed
+ * for being public. QXmlName, in contrast, is only a public marker,
+ * that for instance uses a qint64 instead of qint32, such that we in
+ * the future can use that, if needed.
+ */
+
+#include "qnamepool_p.h"
+#include "qxmlname.h"
+#include "qxmlnamepool.h"
+#include "qxpathhelper_p.h"
+#include "private/qxmlutils_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QXmlName
+ \brief The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ QXmlName represents the name of an XML node in a way that
+ is both efficient and safe for comparing names. Normally,
+ an XML node represents an XML element or attribute, but
+ QXmlName can also represent the names of other kinds of
+ nodes, e.g., QAbstractXmlReceiver::processingInstruction()
+ and QAbstractXmlReceiver::namespaceBinding().
+
+ The name of an XML node has three components: The \e {namespace
+ URI}, the \e {local name}, and the \e {prefix}. To see what these
+ refer to in XML, consider the following snippet.
+
+ \quotefile doc/src/snippets/patternist/mobeyDick.xml
+
+ For the element named \e book, localName() returns \e book,
+ namespaceUri() returns \e http://example.com/MyDefault,
+ and prefix() returns an empty string. For the element named
+ \e title, localName() returns \e title, namespaceUri() returns
+ \e http://purl.org/dc/elements/1.1, and prefix() returns \e dc.
+
+ To ensure that operations with QXmlName are efficient, e.g.,
+ copying names and comparing them, each instance of QXmlName is
+ associated with a \l {QXmlNamePool} {name pool}, which must be
+ specified at QXmlName construction time. The three components
+ of the QXmlName, i.e., the namespace URI, the local name, and
+ the prefix, are stored in the name pool mapped to identifiers
+ so they can be shared. For this reason, the only way to create
+ a valid instance of QXmlName is to use the class constructor,
+ where the \l {QXmlNamePool} {name pool}, local name, namespace
+ URI, and prefix must all be specified.
+
+ Note that QXmlName's default constructor constructs a null
+ instance. It is typically used for allocating unused entries
+ in collections of QXmlName.
+
+ A side effect of associating each instance of QXmlName with
+ a \l {QXmlNamePool} {name pool} is that each instance of
+ QXmlName is tied to the QXmlNamePool with which it was created.
+ However, the QXmlName class does not keep track of the name pool,
+ so all the accessor functions, e.g., namespaceUri(), prefix(),
+ localName(), and toClarkName() require that the correct name
+ pool be passed to them. Failure to provide the correct name
+ pool to these accessor functions results in undefined behavior.
+
+ Note that a \l {QXmlNamePool} {name pool} is \e not an XML
+ namespace. One \l {QXmlNamePool} {name pool} can represent
+ instances of QXmlName from different XML namespaces, and the
+ instances of QXmlName from one XML namespace can be distributed
+ over multiple \l {QXmlNamePool} {name pools}.
+
+ \target Comparing QXmlNames
+ \section1 Comparing QXmlNames
+
+ To determine what a QXmlName refers to, the \e {namespace URI}
+ and the \e {local name} are used. The \e prefix is not used
+ because the prefix is simply a shorthand name for use in place
+ of the normally much longer namespace URI. Nor is the prefix
+ used in name comparisons. For example, the following two element
+ nodes represent the same element and compare equal.
+
+ \quotefile doc/src/snippets/patternist/svgDocumentElement.xml
+
+ \quotefile doc/src/snippets/patternist/xsvgDocumentElement.xml
+
+ Although the second name has the prefix \e x, the two names compare
+ equal as instances of QXmlName, because the prefix is not used in
+ the comparison.
+
+ A local name can never be an empty string, although the prefix and
+ namespace URI can. If the prefix is not empty, the namespace URI
+ cannot be empty. Local names and prefixes must be valid
+ \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {NCNames},
+ e.g., \e abc.def or \e abc123.
+
+ QXmlName represents what is sometimes called an \e {expanded QName},
+ or simply a QName.
+
+ \sa {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {Namespaces in XML 1.0 (Second Edition), [4] NCName}
+ */
+
+/*!
+ \enum QXmlName::Constant
+ \internal
+ Various constants used in the QPatternist::NamePool and QXmlName.
+
+ Setting of the mask enums use essentially this:
+
+ \quotefile doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp
+
+ The masks, such as LocalNameMask, are positive. That is, for the
+ area which the name resides, the bits are set.
+ */
+
+/*!
+ Constructs a QXmlName instance that inserts \a localName,
+ \a namespaceURI and \a prefix into \a namePool if they aren't
+ already there. The accessor functions namespaceUri(), prefix(),
+ localName(), and toClarkName() must be passed the \a namePool
+ used here, so the \a namePool must remain in scope while the
+ accessor functions might be used. However, two instances can
+ be compared with \e {==} or \e {!=} and copied without the
+ \a namePool.
+
+ The user guarantees that the string components are valid for a
+ QName. In particular, the local name, and the prefix (if present),
+ must be valid \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName}
+ {NCNames}. The function isNCName() can be used to test validity
+ of these names. The namespace URI should be an absolute URI.
+ QUrl::isRelative() can be used to test whether the namespace URI
+ is relative or absolute. Finally, providing a prefix is not valid
+ when no namespace URI is provided.
+
+ \a namePool is not copied. Nor is the reference to it retained
+ in this instance. This constructor inserts the three strings
+ into \a namePool.
+ */
+QXmlName::QXmlName(QXmlNamePool &namePool,
+ const QString &localName,
+ const QString &namespaceURI,
+ const QString &prefix)
+{
+ Q_ASSERT_X(prefix.isEmpty() || QXmlUtils::isNCName(prefix), Q_FUNC_INFO,
+ "The prefix is invalid, maybe the arguments were mixed up?");
+ Q_ASSERT_X(QXmlUtils::isNCName(localName), Q_FUNC_INFO,
+ "The local name is invalid, maybe the arguments were mixed up?");
+
+ m_qNameCode = namePool.d->allocateQName(namespaceURI, localName, prefix).code();
+}
+
+/*!
+ \typedef QXmlName::Code
+ \internal
+
+ Stores the \l {QXmlNamePool} {name pool} identifiers for
+ the namespace URI, local name, and prefix.
+ */
+
+/*!
+ Returns true if this QXmlName is not initialized with a
+ valid combination of \e {namespace URI}, \e {local name},
+ and \e {prefix}.
+
+ A valid local name is always required. The prefix and
+ namespace URI can be empty, but if the prefix is not empty,
+ the namespace URI must not be empty. Local names and
+ prefixes must be valid
+ \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {NCNames},
+ e.g., \e abc.def or \e abc123.
+ */
+bool QXmlName::isNull() const
+{
+ return m_qNameCode == InvalidCode;
+}
+
+/*!
+ Constructs an uninitialized QXmlName. To build
+ a valid QXmlName, you normally use the other constructor, which
+ takes a \l {QXmlNamePool} {name pool}, namespace URI, local name,
+ and prefix as parameters. But you can also use this constructor
+ to build a null QXmlName and then assign an existing QXmlName
+ to it.
+
+ \sa isNull()
+ */
+QXmlName::QXmlName() : m_qNameCode(InvalidCode)
+{
+}
+
+/*!
+ \fn QXmlName::QXmlName(const NamespaceCode uri,
+ const LocalNameCode ln,
+ const PrefixCode p = 0)
+ \internal
+ */
+
+/*!
+ \fn QXmlName::hasPrefix() const
+ \internal
+
+ Returns true if this QXmlName has a non-empty prefix. If this
+ function returns true, hasNamespace() will also return true,
+ because a QXmlName can't have a prefix if it doesn't have a
+ namespace URI.
+ */
+
+/*!
+ \fn bool QXmlName::hasNamespace() const
+ \internal
+
+ Returns true if this QXmlName has a non-empty namespace URI.
+ */
+
+/*!
+ \fn Code QXmlName::code() const
+ \internal
+
+ Returns the internal code that contains the id codes for the
+ local name, prefix and namespace URI. It is opaque when used
+ outside QXmlName, but it can be useful when one wants to put
+ a QXmlName in a hash, and the prefix is significant.
+ */
+
+/*!
+ Returns true if this QXmlName is equal to \a other; otherwise false.
+ Two QXmlNames are equal if their namespace URIs are the same \e and
+ their local names are the same. The prefixes are ignored.
+
+ Note that it is meaningless to compare two instances of QXmlName
+ that were created with different \l {QXmlNamePool} {name pools},
+ but the attempt is not detected and the behavior is undefined.
+
+ \sa operator!=()
+ */
+bool QXmlName::operator==(const QXmlName &other) const
+{
+ return (m_qNameCode & ExpandedNameMask) == (other.m_qNameCode & ExpandedNameMask);
+}
+
+/*!
+ Returns true if this QXmlName is \e not equal to \a other;
+ otherwise false. Two QXmlNames are equal if their namespace
+ URIs are the same \e and their local names are the same. They
+ are not equal if either their namespace URIs differ or their
+ local names differ. Their prefixes are ignored.
+
+ Note that it is meaningless to compare two instances of QXmlName
+ that were created with different \l {QXmlNamePool} {name pools},
+ but the attempt is not detected and the behavior is undefined.
+
+ \sa operator==()
+ */
+bool QXmlName::operator!=(const QXmlName &other) const
+{
+ return !operator==(other);
+}
+
+/*!
+ \fn bool QXmlName::isLexicallyEqual(const QXmlName &other) const
+ \internal
+
+ Returns true if this and \a other are lexically equal. Two
+ QXmlNames are lexically equal if their local names are equal
+ \e and their prefixes are equal.
+ */
+
+/*!
+ \fn uint qHash(const QXmlName &name)
+ \since 4.4
+ \relates QXmlName
+
+ Computes a hash key from the local name and the namespace
+ URI in \a name. The prefix in \a name is not used in the computation.
+ */
+uint qHash(const QXmlName &name)
+{
+ return name.m_qNameCode & QXmlName::ExpandedNameMask;
+}
+
+/*!
+ Returns the namespace URI.
+
+ Note that for efficiency, the namespace URI string is not
+ stored in the QXmlName but in the \l {QXmlNamePool} that was
+ passed to the constructor. Hence, that same \a namePool must
+ be passed to this function, so it can be used for looking up
+ the namespace URI.
+ */
+QString QXmlName::namespaceUri(const QXmlNamePool &namePool) const
+{
+ if(isNull())
+ return QString();
+ else
+ return namePool.d->stringForNamespace(namespaceURI());
+}
+
+/*!
+ Returns the prefix.
+
+ Note that for efficiency, the prefix string is not stored in
+ the QXmlName but in the \l {QXmlNamePool} that was passed to
+ the constructor. Hence, that same \a namePool must be passed
+ to this function, so it can be used for looking up the prefix.
+ */
+QString QXmlName::prefix(const QXmlNamePool &namePool) const
+{
+ if(isNull())
+ return QString();
+ else
+ return namePool.d->stringForPrefix(prefix());
+}
+
+/*!
+ Returns the local name.
+
+ Note that for efficiency, the local name string is not stored
+ in the QXmlName but in the \l {QXmlNamePool} that was passed to
+ the constructor. Hence, that same \a namePool must be passed
+ to this function, so it can be used for looking up the
+ local name.
+ */
+QString QXmlName::localName(const QXmlNamePool &namePool) const
+{
+ if(isNull())
+ return QString();
+ else
+ return namePool.d->stringForLocalName(localName());
+}
+
+/*!
+ Returns this QXmlName formatted as a Clark Name. For example,
+ if the local name is \c html, the prefix is \c x, and the
+ namespace URI is \c {http://www.w3.org/1999/xhtml/},
+ then the Clark Name returned is:
+
+ \code
+ {http://www.w3.org/1999/xhtml/}x:html.
+ \endcode
+
+ If the local name is \e {MyWidget} and the namespace is empty,
+ the Clark Name returned is:
+
+ \code
+ MyWidget
+ \endcode
+
+ Note that for efficiency, the namespace URI, local name, and
+ prefix strings are not stored in the QXmlName but in the
+ \l {QXmlNamePool} that was passed to the constructor. Hence,
+ that same \a namePool must be passed to this function, so it
+ can be used for looking up the three string components.
+
+ This function can be useful for debugging.
+
+ \sa {http://www.jclark.com/xml/xmlns.htm} {XML Namespaces, James Clark}
+ \sa fromClarkName()
+ */
+QString QXmlName::toClarkName(const QXmlNamePool &namePool) const
+{
+ return namePool.d->toClarkName(*this);
+}
+
+/*!
+ Assigns \a other to \e this and returns \e this.
+ */
+QXmlName &QXmlName::operator=(const QXmlName &other)
+{
+ m_qNameCode = other.m_qNameCode;
+ return *this;
+}
+
+/*!
+ Returns true if \a candidate is an \c NCName. An \c NCName
+ is a string that can be used as a name in XML and XQuery,
+ e.g., the prefix or local name in an element or attribute,
+ or the name of a variable.
+
+ \sa {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {Namespaces in XML 1.0 (Second Edition), [4] NCName}
+ */
+bool QXmlName::isNCName(const QString &candidate)
+{
+ return QXmlUtils::isNCName(candidate);
+}
+
+/*!
+ Converts \a clarkName into a QXmlName, inserts into \a namePool, and
+ returns it.
+
+ A clark name is a way to present a full QName with only one string, where
+ the namespace cannot contain braces. Here are a couple of examples:
+
+ \table
+ \header
+ \o Clark Name
+ \o Description
+ \row
+ \o \c html
+ \o The local name \c html, in no namespace
+ \row
+ \o \c {http://www.w3.org/1999/xhtml}html
+ \o The local name \c html, in the XHTML namespace
+ \row
+ \o \c {http://www.w3.org/1999/xhtml}my:html
+ \o The local name \c html, in the XHTML namespace, with the prefix \c my
+ \endtable
+
+ If the namespace contains braces, the returned value is either invalid or
+ has undefined content.
+
+ If \a clarkName is an invalid name, a default constructed QXmlName is
+ returned.
+
+ \since 4.5
+ \sa toClarkName()
+ */
+QXmlName QXmlName::fromClarkName(const QString &clarkName,
+ const QXmlNamePool &namePool)
+{
+ return namePool.d->fromClarkName(clarkName);
+}
+
+/*!
+ \typedef QXmlName::LocalNameCode
+ \internal
+ */
+
+/*!
+ \typedef QXmlName::PrefixCode
+ \internal
+ */
+
+/*!
+ \typedef QXmlName::NamespaceCode
+ \internal
+ */
+
+/*!
+ \fn void QXmlName::setLocalName(const LocalNameCode c)
+ \internal
+*/
+
+/*!
+ \fn LocalNameCode QXmlName::localName() const
+ \internal
+*/
+
+/*!
+ \fn PrefixCode QXmlName::prefix() const
+ \internal
+*/
+
+/*!
+ \fn NamespaceCode QXmlName::namespaceURI() const
+ \internal
+*/
+
+/*!
+ \fn void QXmlName::setNamespaceURI(const NamespaceCode c)
+ \internal
+*/
+
+/*!
+ \fn void QXmlName::setPrefix(const PrefixCode c)
+ \internal
+*/
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qxmlname.h b/src/xmlpatterns/api/qxmlname.h
new file mode 100644
index 0000000..8350302
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlname.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLNAME_H
+#define QXMLNAME_H
+
+#include <QtCore/QString>
+#include <QtCore/QMetaType>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QXmlName;
+class QXmlNamePool;
+Q_XMLPATTERNS_EXPORT uint qHash(const QXmlName &name);
+
+class Q_XMLPATTERNS_EXPORT QXmlName
+{
+private:
+ enum Constant
+ {
+ LocalNameOffset = 0,
+ LocalNameLength = 12,
+ NamespaceOffset = LocalNameLength,
+ NamespaceLength = 9,
+ PrefixLength = 9,
+ InvalidCode = 1 << 31,
+ NamespaceMask = ((1 << ((NamespaceOffset + NamespaceLength) - NamespaceOffset)) - 1) << NamespaceOffset,
+ LocalNameMask = ((1 << ((LocalNameOffset + LocalNameLength) - LocalNameOffset)) - 1) << LocalNameOffset,
+ PrefixOffset = LocalNameLength + NamespaceLength,
+ PrefixMask = ((1 << ((PrefixOffset + PrefixLength) - PrefixOffset)) - 1) << PrefixOffset,
+ MaximumPrefixes = (PrefixMask >> PrefixOffset) - 1,
+ MaximumLocalNames = (LocalNameMask >> LocalNameOffset) - 1,
+ MaximumNamespaces = (NamespaceMask >> NamespaceOffset) - 1,
+ ExpandedNameMask = LocalNameMask | NamespaceMask,
+ LexicalQNameMask = LocalNameMask | PrefixMask
+ };
+
+public:
+
+ typedef qint16 NamespaceCode;
+ typedef NamespaceCode PrefixCode;
+ typedef NamespaceCode LocalNameCode;
+
+ QXmlName();
+
+ QXmlName(QXmlNamePool &namePool,
+ const QString &localName,
+ const QString &namespaceURI = QString(),
+ const QString &prefix = QString());
+
+ QString namespaceUri(const QXmlNamePool &query) const;
+ QString prefix(const QXmlNamePool &query) const;
+ QString localName(const QXmlNamePool &query) const;
+ QString toClarkName(const QXmlNamePool &query) const;
+ bool operator==(const QXmlName &other) const;
+ bool operator!=(const QXmlName &other) const;
+ QXmlName &operator=(const QXmlName &other);
+ bool isNull() const;
+ static bool isNCName(const QString &candidate);
+ static QXmlName fromClarkName(const QString &clarkName,
+ const QXmlNamePool &namePool);
+
+ /* The members below are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+ typedef qint64 Code;
+
+ inline QXmlName(const NamespaceCode uri,
+ const LocalNameCode ln,
+ const PrefixCode p = 0);
+ /* The implementation for these functions are in utils/qnamepool_p.h. */
+ inline LocalNameCode localName() const;
+ inline PrefixCode prefix() const;
+ inline bool hasPrefix() const;
+ inline bool hasNamespace() const;
+ inline NamespaceCode namespaceURI() const;
+ inline bool isLexicallyEqual(const QXmlName &other) const;
+ inline void setPrefix(const PrefixCode c);
+ inline void setNamespaceURI(const NamespaceCode c);
+ inline void setLocalName(const LocalNameCode c);
+ inline Code code() const;
+
+ friend Q_XMLPATTERNS_EXPORT uint qHash(const QXmlName &);
+
+private:
+ inline QXmlName(const int c) : m_qNameCode(c)
+ {
+ }
+
+ Code m_qNameCode;
+};
+
+Q_DECLARE_TYPEINFO(QXmlName, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QXmlName) /* This macro must appear after QT_END_NAMESPACE. */
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlnamepool.cpp b/src/xmlpatterns/api/qxmlnamepool.cpp
new file mode 100644
index 0000000..bd1f67f
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlnamepool.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnamepool_p.h"
+#include "qxmlnamepool.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QXmlNamePool
+ \brief The QXmlNamePool class is a table of shared strings referenced by instances of QXmlName.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ QXmlNamePool is used to optimize operations on instances of
+ QXmlName. An instance of QXmlName represents an XML name in
+ a way that allows the XML name to be compared and passed around
+ efficiently. The efficiency is achieved by storing the strings
+ comprising the XML names in an instance of QXmlNamePool, where
+ they are mapped to binary identifiers, which are then packed
+ into a key which is stored in the QXmlName.
+
+ This means that each instance of QXmlName is tied to the name
+ pool it was created with, and that name pool should be kept in
+ scope and used to create all instances of QXmlName that might
+ be compared. Note also that the name pool is required if you
+ must reconstitute the QXmlName as text, or if you must access
+ any of its component strings, so although instances of
+ QXmlName can be compared without reference to a name pool, the
+ name pool must be kept in scope if the name's strings must be
+ accessed later.
+
+ \sa QXmlName
+ \sa QXmlQuery::namePool()
+ */
+
+/*!
+ Constructs an empty name pool.
+ */
+QXmlNamePool::QXmlNamePool() : d(new QPatternist::NamePool())
+{
+}
+
+/*!
+ Constructs a copy of the \a other name pool.
+ */
+QXmlNamePool::QXmlNamePool(const QXmlNamePool &other) : d(other.d)
+{
+}
+
+/*!
+ Destroys the name pool. Instances of QXmlName constructed
+ with this name pool can still be compared after this destructor
+ is called, but their text strings cannot be accessed.
+ */
+QXmlNamePool::~QXmlNamePool()
+{
+}
+
+QXmlNamePool::QXmlNamePool(QPatternist::NamePool *namePool) : d(QExplicitlySharedDataPointer<QPatternist::NamePool>(namePool))
+{
+}
+
+/*!
+ Assigns the \a other name pool to this one.
+ */
+QXmlNamePool &QXmlNamePool::operator=(const QXmlNamePool &other)
+{
+ d = other.d;
+ return *this;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qxmlnamepool.h b/src/xmlpatterns/api/qxmlnamepool.h
new file mode 100644
index 0000000..df9285c
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlnamepool.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLNAMEPOOL_H
+#define QXMLNAMEPOOL_H
+
+#include <QtCore/QSharedData>
+#include <QtCore/QString>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+namespace QPatternist
+{
+ class NamePool;
+ class XsdSchemaParser;
+ class XsdValidatingInstanceReader;
+}
+
+namespace QPatternistSDK
+{
+ class Global;
+}
+
+class QXmlQueryPrivate;
+class QXmlName;
+
+class Q_XMLPATTERNS_EXPORT QXmlNamePool
+{
+public:
+ QXmlNamePool();
+ QXmlNamePool(const QXmlNamePool &other);
+ ~QXmlNamePool();
+ QXmlNamePool &operator=(const QXmlNamePool &other);
+
+private:
+ QXmlNamePool(QPatternist::NamePool *namePool);
+ friend class QXmlQueryPrivate;
+ friend class QXmlQuery;
+ friend class QXmlSchemaPrivate;
+ friend class QXmlSchemaValidatorPrivate;
+ friend class QXmlSerializerPrivate;
+ friend class QXmlName;
+ friend class QPatternist::XsdSchemaParser;
+ friend class QPatternist::XsdValidatingInstanceReader;
+ friend class QPatternistSDK::Global;
+ QExplicitlySharedDataPointer<QPatternist::NamePool> d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlpatternistcli_p.h b/src/xmlpatterns/api/qxmlpatternistcli_p.h
new file mode 100644
index 0000000..328adcf
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlpatternistcli_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the XMLPatterns 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Cli_h
+#define Patternist_Cli_h
+
+#include <QCoreApplication>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlPatternistCLI
+{
+public:
+ Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI)
+private:
+ inline QXmlPatternistCLI();
+ Q_DISABLE_COPY(QXmlPatternistCLI)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp
new file mode 100644
index 0000000..d74a536
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlquery.cpp
@@ -0,0 +1,1209 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QBuffer>
+#include <QtCore/QStringList>
+#include <QtXmlPatterns/QXmlFormatter>
+
+#include "qacceltreeresourceloader_p.h"
+#include "qcommonvalues_p.h"
+#include "qxmlresultitems.h"
+#include "qxmlresultitems_p.h"
+#include "qxmlserializer.h"
+#include "qxpathhelper_p.h"
+
+#include "qxmlquery.h"
+#include "qxmlquery_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QXmlQuery
+
+ \brief The QXmlQuery class performs XQueries on XML data, or on non-XML data modeled to look like XML.
+
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ The QXmlQuery class compiles and executes queries written in the
+ \l {http://www.w3.org/TR/xquery/}{XQuery language}. QXmlQuery is
+ typically used to query XML data, but it can also query non-XML
+ data that has been modeled to look like XML.
+
+ Using QXmlQuery to query XML data, as in the snippet below, is
+ simple because it can use the built-in \l {QAbstractXmlNodeModel}
+ {XML data model} as its delegate to the underlying query engine for
+ traversing the data. The built-in data model is specified in \l
+ {http://www.w3.org/TR/xpath-datamodel/} {XQuery 1.0 and XPath 2.0
+ Data Model}.
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0
+
+ The example uses QXmlQuery to match the first paragraph of an XML
+ document and then \l {QXmlSerializer} {output the result} to a
+ device as XML.
+
+ Using QXmlQuery to query \e {non-XML} data requires writing a
+ subclass of QAbstractXmlNodeModel to use as a replacement for the
+ built-in XML data model. The custom data model will be able to
+ traverse the non-XML data as required by the QAbstractXmlNodeModel
+ interface. An instance of this custom data model then becomes the
+ delegate used by the query engine to traverse the non-XML data. For
+ an example of how to use QXmlQuery to query non-XML data, see the
+ documentation for QAbstractXmlNodeModel.
+
+ \section1 Running XQueries
+
+ To run a query set up with QXmlQuery, call one of the evaluation
+ functions.
+
+ \list
+
+ \o evaluateTo(QAbstractXmlReceiver *) is called with a pointer to an
+ XML \l {QAbstractXmlReceiver} {receiver}, which receives the query
+ results as a sequence of callbacks. The receiver callback class is
+ like the callback class used for translating the output of a SAX
+ parser. QXmlSerializer, for example, is a receiver callback class
+ for translating the sequence of callbacks for output as unformatted
+ XML text.
+
+ \endlist
+
+ \list
+
+ \o evaluateTo(QXmlResultItems *) is called with a pointer to an
+ iterator for an empty sequence of query \l {QXmlResultItems} {result
+ items}. The Java-like iterator allows the query results to be
+ accessed sequentially.
+
+ \endlist
+
+ \list
+
+ \o evaluateTo(QStringList *) is like evaluateTo(QXmlResultItems *),
+ but the query must evaluate to a sequence of strings.
+
+ \endlist
+
+ \section1 Running XPath Expressions
+
+ The XPath language is a subset of the XQuery language, so
+ running an XPath expression is the same as running an XQuery
+ query. Pass the XPath expression to QXmlQuery using setQuery().
+
+ \section1 Running XSLT stylesheets
+
+ Running an XSLT stylesheet is like running an XQuery, except that
+ when you construct your QXmlQuery, you must pass QXmlQuery::XSLT20
+ to tell QXmlQuery to interpret whatever it gets from setQuery() as
+ an XSLT stylesheet instead of as an XQuery. You must also set the
+ input document by calling setFocus().
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 7
+
+ \note Currently, setFocus() must be called \e before setQuery() when
+ using XSLT.
+
+ Another way to run an XSLT stylesheet is to use the \c xmlpatterns
+ command line utility.
+
+ \code
+ xmlpatterns myStylesheet.xsl myInput.xml
+ \endcode
+
+ \note For the current release, XSLT support should be considered
+ experimental. See section \l{XQuery#XSLT 2.0} {XSLT conformance} for
+ details.
+
+ Stylesheet parameters are bound using bindVariable().
+
+ \section1 Binding A Query To A Starting Node
+
+ When a query is run on XML data, as in the snippet above, the
+ \c{doc()} function returns the node in the built-in data model where
+ the query evaluation will begin. But when a query is run on a custom
+ node model containing non-XML data, one of the bindVariable()
+ functions must be called to bind a variable name to a starting node
+ in the custom model. A $variable reference is used in the XQuery
+ text to access the starting node in the custom model. It is not
+ necessary to declare the variable name external in the query. See
+ the example in the documentation for QAbstractXmlNodeModel.
+
+ \section1 Reentrancy and Thread-Safety
+
+ QXmlQuery is reentrant but not thread-safe. It is safe to use the
+ QxmlQuery copy constructor to create a copy of a query and run the
+ same query multiple times. Behind the scenes, QXmlQuery will reuse
+ resources such as opened files and compiled queries to the extent
+ possible. But it is not safe to use the same instance of QXmlQuery
+ in multiple threads.
+
+ \section1 Error Handling
+
+ Errors can occur during query evaluation. Examples include type
+ errors and file loading errors. When an error occurs:
+
+ \list
+
+ \o The error message is sent to the messageHandler().
+
+ \o QXmlResultItems::hasError() will return \c{true}, or
+ evaluateTo() will return \c{false};
+
+ \o The results of the evaluation are undefined.
+
+ \endlist
+
+ \section1 Resource Management
+
+ When a query runs, it parses documents, allocating internal data
+ structures to hold them, and it may load other resources over the
+ network. It reuses these allocated resources when possible, to
+ avoid having to reload and reparse them.
+
+ When setQuery() is called, the query text is compiled into an
+ internal data structure and optimized. The optimized form can
+ then be reused for multiple evaluations of the query. Since the
+ compile-and-optimize process can be expensive, repeating it for
+ the same query should be avoided by using a separate instance of
+ QXmlQuery for each query text.
+
+ Once a document has been parsed, its internal representation is
+ maintained in the QXmlQuery instance and shared among multiple
+ QXmlQuery instances.
+
+ An instance of QCoreApplication must exist before QXmlQuery can be
+ used.
+
+ \section1 Event Handling
+
+ When QXmlQuery accesses resources (e.g., calling \c fn:doc() to load a file,
+ or accessing a device via a bound variable), the event loop is used, which
+ means events will be processed. To avoid processing events when QXmlQuery
+ accesses resources, create your QXmlQuery instance in a separate thread.
+ */
+
+/*!
+ \enum QXmlQuery::QueryLanguage
+ \since 4.5
+
+ Specifies whether you want QXmlQuery to interpret the input to
+ setQuery() as an XQuery or as an XSLT stylesheet.
+
+ \value XQuery10 XQuery 1.0.
+ \value XSLT20 XSLT 2.0
+ \omitvalue XmlSchema11IdentityConstraintSelector The selector, the restricted
+ XPath pattern found in W3C XML Schema 1.1 for uniqueness
+ contraints. Apart from restricting the syntax, the type check stage
+ for the expression assumes a sequence of nodes to be the focus.
+ \omitvalue XmlSchema11IdentityConstraintField The field, the restricted
+ XPath pattern found in W3C XML Schema 1.1 for uniqueness
+ contraints. Apart from restricting the syntax, the type check stage
+ for the expression assumes a sequence of nodes to be the focus.
+ \omitvalue XPath20 Signifies XPath 2.0. Has no effect in the public API, it's
+ used internally. As With XmlSchema11IdentityConstraintSelector and
+ XmlSchema11IdentityConstraintField, the type check stage
+ for the expression assumes a sequence of nodes to be the focus.
+
+ \sa setQuery()
+ */
+
+// ### Qt5: Merge constructor overloads
+/*!
+ Constructs an invalid, empty query that cannot be used until
+ setQuery() is called.
+
+ \note This constructor must not be used if you intend to use
+ this QXmlQuery to process XSL-T stylesheets. The other constructor
+ must be used in that case.
+ */
+QXmlQuery::QXmlQuery() : d(new QXmlQueryPrivate())
+{
+}
+
+/*!
+ Constructs a QXmlQuery that is a copy of \a other. The new
+ instance will share resources with the existing query
+ to the extent possible.
+ */
+QXmlQuery::QXmlQuery(const QXmlQuery &other) : d(new QXmlQueryPrivate(*other.d))
+{
+ /* First we have invoked QXmlQueryPrivate's synthesized copy constructor.
+ * Keep this section in sync with QXmlQuery::operator=(). */
+ d->detach();
+}
+
+/*!
+ Constructs a query that will use \a np as its name pool. The query
+ cannot be evaluated until setQuery() has been called.
+ */
+QXmlQuery::QXmlQuery(const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
+{
+}
+
+/*!
+
+ Constructs a query that will be used to run Xqueries or XSL-T
+ stylesheets, depending on the value of \a queryLanguage. It will use
+ \a np as its name pool.
+
+ \note If your QXmlQuery will process XSL-T stylesheets, this
+ constructor must be used. The default constructor can only
+ create instances of QXmlQuery for running XQueries.
+
+ \note The XSL-T support in this release is considered experimental.
+ See the \l{XQuery#XSLT 2.0} {XSLT conformance} for details.
+
+ \since 4.5
+ \sa queryLanguage()
+ */
+QXmlQuery::QXmlQuery(QueryLanguage queryLanguage,
+ const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
+{
+ d->queryLanguage = queryLanguage;
+}
+
+/*!
+ Destroys this QXmlQuery.
+ */
+QXmlQuery::~QXmlQuery()
+{
+ delete d;
+}
+
+/*!
+ Assigns \a other to this QXmlQuery instance.
+ */
+QXmlQuery &QXmlQuery::operator=(const QXmlQuery &other)
+{
+ /* Keep this section in sync with QXmlQuery::QXmlQuery(const QXmlQuery &).
+ */
+ if(d != other.d)
+ {
+ *d = *other.d;
+ d->detach();
+ }
+
+ return *this;
+}
+
+/*!
+ Changes the \l {QAbstractMessageHandler}{message handler} for this
+ QXmlQuery to \a aMessageHandler. The query sends all compile and
+ runtime messages to this message handler. QXmlQuery does not take
+ ownership of \a aMessageHandler.
+
+ Normally, the default message handler is sufficient. It writes
+ compile and runtime messages to \e stderr. The default message
+ handler includes color codes if \e stderr can render colors.
+
+ Note that changing the message handler after the query has been
+ compiled has no effect, i.e. the query uses the same message handler
+ at runtime that it uses at compile time.
+
+ When QXmlQuery calls QAbstractMessageHandler::message(),
+ the arguments are as follows:
+
+ \table
+ \header
+ \o message() argument
+ \o Semantics
+ \row
+ \o QtMsgType type
+ \o Only QtWarningMsg and QtFatalMsg are used. The former
+ identifies a compile or runtime warning, while the
+ latter identifies a dynamic or static error.
+ \row
+ \o const QString & description
+ \o An XHTML document which is the actual message. It is translated
+ into the current language.
+ \row
+ \o const QUrl &identifier
+ \o Identifies the error with a URI, where the fragment is
+ the error code, and the rest of the URI is the error namespace.
+ \row
+ \o const QSourceLocation & sourceLocation
+ \o Identifies where the error occurred.
+ \endtable
+
+ */
+void QXmlQuery::setMessageHandler(QAbstractMessageHandler *aMessageHandler)
+{
+ d->messageHandler = aMessageHandler;
+}
+
+/*!
+ Returns the message handler that handles compile and runtime
+ messages for this QXmlQuery.
+ */
+QAbstractMessageHandler *QXmlQuery::messageHandler() const
+{
+ return d->messageHandler;
+}
+
+/*!
+ Sets this QXmlQuery to an XQuery read from the \a sourceCode
+ device. The device must have been opened with at least
+ QIODevice::ReadOnly.
+
+ \a documentURI represents the query obtained from the \a sourceCode
+ device. It is the base URI of the static context, as defined in the
+ \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
+ internally to resolve relative URIs that appear in the query, and
+ for message reporting. \a documentURI can be empty. If it is empty,
+ the \l{QCoreApplication::applicationFilePath()} {application file
+ path} is used. If it is not empty, it may be either relative or
+ absolute. If it is relative, it is resolved itself against the
+ \l {QCoreApplication::applicationFilePath()} {application file
+ path} before it is used. If \a documentURI is neither a valid URI
+ nor empty, the result is undefined.
+
+ If the query contains a static error (e.g. syntax error), an error
+ message is sent to the messageHandler(), and isValid() will return
+ \e false.
+
+ Variables must be bound before setQuery() is called.
+
+ The encoding of the XQuery in \a sourceCode is detected internally
+ using the rules for setting and detecting encoding of XQuery files,
+ which are explained in the \l {http://www.w3.org/TR/xquery/}
+ {XQuery language}.
+
+ If \a sourceCode is \c null or not readable, or if \a documentURI is not
+ a valid URI, behavior is undefined.
+ \sa isValid()
+ */
+void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI)
+{
+ if(!sourceCode)
+ {
+ qWarning("A null QIODevice pointer cannot be passed.");
+ return;
+ }
+
+ if(!sourceCode->isReadable())
+ {
+ qWarning("The device must be readable.");
+ return;
+ }
+
+ d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(documentURI);
+ d->expression(sourceCode);
+}
+
+/*!
+ \overload
+ The behavior and requirements of this function are the same as for
+ setQuery(QIODevice*, const QUrl&), after the XQuery has been read
+ from the IO device into a string. Because \a sourceCode is already
+ a Unicode string, detection of its encoding is unnecessary.
+*/
+void QXmlQuery::setQuery(const QString &sourceCode, const QUrl &documentURI)
+{
+ Q_ASSERT_X(documentURI.isEmpty() || documentURI.isValid(), Q_FUNC_INFO,
+ "The document URI must be valid.");
+
+ QByteArray query(sourceCode.toUtf8());
+ QBuffer buffer(&query);
+ buffer.open(QIODevice::ReadOnly);
+
+ setQuery(&buffer, documentURI);
+}
+
+/*!
+ Sets this QXmlQuery to the XQuery read from the \a queryURI. Use
+ isValid() after calling this function. If an error occurred reading
+ \a queryURI, e.g., the query does not exist, cannot be read, or is
+ invalid, isValid() will return \e false.
+
+ The supported URI schemes are the same as those in the XQuery
+ function \c{fn:doc}, except that queryURI can be the object of
+ a variable binding.
+
+ \a baseURI is the Base URI of the static context, as defined in the
+ \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
+ internally to resolve relative URIs that appear in the query, and
+ for message reporting. If \a baseURI is empty, \a queryURI is used.
+ Otherwise, \a baseURI is used, and it is resolved against the \l
+ {QCoreApplication::applicationFilePath()} {application file path} if
+ it is relative.
+
+ If \a queryURI is empty or invalid, or if \a baseURI is invalid,
+ the behavior of this function is undefined.
+ */
+void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI)
+{
+ Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid.");
+
+ const QUrl canonicalURI(QPatternist::XPathHelper::normalizeQueryURI(queryURI));
+ Q_ASSERT(canonicalURI.isValid());
+ Q_ASSERT(!canonicalURI.isRelative());
+ Q_ASSERT(baseURI.isValid() || baseURI.isEmpty());
+
+ d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI);
+
+ QPatternist::AutoPtr<QIODevice> result;
+
+ try
+ {
+ result.reset(QPatternist::AccelTreeResourceLoader::load(canonicalURI, d->m_networkAccessDelegator,
+ d->staticContext()));
+ }
+ catch(const QPatternist::Exception)
+ {
+ /* We do nothing, result will be 0. */
+ }
+
+ if(result)
+ {
+ setQuery(result.data(), d->queryURI);
+ result->close();
+ }
+ else
+ d->recompileRequired();
+}
+
+/*!
+ Binds the variable \a name to the \a value so that $\a name can be
+ used from within the query to refer to the \a value.
+
+ \a name must not be \e null. \a {name}.isNull() must return false.
+ If \a name has already been bound by a previous bindVariable() call,
+ its previous binding will be overridden.
+
+ If \a {value} is null so that \a {value}.isNull() returns true, and
+ \a {name} already has a binding, the effect is to remove the
+ existing binding for \a {name}.
+
+ To bind a value of type QString or QUrl, wrap the value in a
+ QVariant such that QXmlItem's QVariant constructor is called.
+
+ All strings processed by the query must be valid XQuery strings,
+ which means they must contain only XML 1.0 characters. However,
+ this requirement is not checked. If the query processes an invalid
+ string, the behavior is undefined.
+
+ \sa QVariant::isValid(), {QtXDM}{How QVariant maps to XQuery's Data Model},
+ QXmlItem::isNull()
+ */
+void QXmlQuery::bindVariable(const QXmlName &name, const QXmlItem &value)
+{
+ if(name.isNull())
+ {
+ qWarning("The variable name cannot be null.");
+ return;
+ }
+
+ const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
+ const QVariant variant(QVariant::fromValue(value));
+
+ /* If the type of the variable changed(as opposed to only the value),
+ * we will have to recompile. */
+ if(vl->invalidationRequired(name, variant) || value.isNull())
+ d->recompileRequired();
+
+ vl->addBinding(name, variant);
+}
+
+/*!
+ \overload
+
+ This function constructs a QXmlName from \a localName using the
+ query's \l {QXmlNamePool} {namespace}. The function then behaves as
+ the overloaded function. It is equivalent to the following snippet.
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 0
+ */
+void QXmlQuery::bindVariable(const QString &localName, const QXmlItem &value)
+{
+ bindVariable(QXmlName(d->namePool, localName), value);
+}
+
+/*!
+ Binds the variable \a name to the \a device so that $\a name can be
+ used from within the query to refer to the \a device. The QIODevice
+ \a device is exposed to the query as a URI of type \c{xs:anyURI},
+ which can be passed to the \c{fn:doc()} function to be read. E.g.,
+ this function can be used to pass an XML document in memory to
+ \c{fn:doc}.
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 1
+
+ The caller must ensure that \a device has been opened with at least
+ QIODevice::ReadOnly prior to this binding. Otherwise, behavior is
+ undefined.
+
+ If the query will access an XML document contained in a QString, use
+ a QBuffer as shown in the following snippet. Suppose \e myQString
+ contains \c{<document>content</document>}
+
+ \snippet doc/src/snippets/qxmlquery/bindingExample.cpp 0
+
+ \a name must not be \e null. \a {name}.isNull() must return false.
+ If \a name has already been bound, its previous binding will be
+ overridden. The URI that \a name evaluates to is arbitrary and may
+ change.
+
+ If the type of the variable binding changes (e.g., if a previous
+ binding by the same name was a QVariant, or if there was no previous
+ binding), isValid() will return \c{false}, and recompilation of the
+ query text is required. To recompile the query, call setQuery(). For
+ this reason, bindVariable() should be called before setQuery(), if
+ possible.
+
+ \note \a device must not be deleted while this QXmlQuery exists.
+*/
+void QXmlQuery::bindVariable(const QXmlName &name, QIODevice *device)
+{
+ if(device && !device->isReadable())
+ {
+ qWarning("A null, or readable QIODevice must be passed.");
+ return;
+ }
+
+ if(name.isNull())
+ {
+ qWarning("The variable name cannot be null.");
+ return;
+ }
+
+ const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
+
+ if(device)
+ {
+ const QVariant variant(QVariant::fromValue(device));
+
+ if(vl->invalidationRequired(name, variant))
+ d->recompileRequired();
+
+ vl->addBinding(name, variant);
+
+ /* We need to tell the resource loader to discard its document, because
+ * the underlying QIODevice has changed, but the variable name is the
+ * same which means that the URI is the same, and hence the resource
+ * loader will return the document for the old QIODevice.
+ */
+ d->resourceLoader()->clear(QUrl(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + d->namePool.d->stringForLocalName(name.localName())));
+ }
+ else
+ {
+ vl->removeBinding(name);
+ d->recompileRequired();
+ }
+}
+
+/*!
+ \overload
+
+ If \a localName is a valid \l {QXmlName::isNCName()} {NCName}, this
+ function is equivalent to the following snippet.
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 2
+
+ A QXmlName is constructed from \a localName, and is passed
+ to the appropriate overload along with \a device.
+
+ \sa QXmlName::isNCName()
+ */
+void QXmlQuery::bindVariable(const QString &localName, QIODevice *device)
+{
+ bindVariable(QXmlName(d->namePool, localName), device);
+}
+
+/*!
+ Evaluates this query and sends the result as a sequence of callbacks
+ to the \l {QAbstractXmlReceiver} {receiver} \a callback. QXmlQuery
+ does not take ownership of \a callback.
+
+ If an error occurs during the evaluation, error messages are sent to
+ messageHandler() and \c false is returned.
+
+ If this query \l {isValid()} {is invalid}, \c{false} is returned
+ and the behavior is undefined. If \a callback is null,
+ behavior is undefined.
+
+ \sa QAbstractXmlReceiver, isValid()
+ */
+bool QXmlQuery::evaluateTo(QAbstractXmlReceiver *callback) const
+{
+ if(!callback)
+ {
+ qWarning("A non-null callback must be passed.");
+ return false;
+ }
+
+ if(isValid())
+ {
+ try
+ {
+ /*
+ * This order is significant. expression() might cause
+ * query recompilation, and as part of that it recreates
+ * the static context. However, if we create the dynamic
+ * context before the query recompilation has been
+ * triggered, it will use the old static context, and
+ * hence old source locations.
+ */
+ const QPatternist::Expression::Ptr expr(d->expression());
+ const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext(callback));
+ callback->startOfSequence();
+ expr->evaluateToSequenceReceiver(dynContext);
+ callback->endOfSequence();
+ return true;
+ }
+ catch(const QPatternist::Exception)
+ {
+ return false;
+ }
+ }
+ else
+ return false;
+}
+
+/*!
+ Attempts to evaluate the query and returns the results in the
+ \a target \l {QStringList} {string list}.
+
+ If the query \l {isValid()} {is valid} and the evaluation succeeds,
+ true is returned. Otherwise, false is returned and the contents of
+ \a target are undefined.
+
+ The query must evaluate to a sequence of \c{xs:string} values. If
+ the query does not evaluate to a sequence of strings, the values can
+ often be converted by adding a call to \c{string()} at the end of
+ the XQuery.
+
+ If \a target is null, the behavior is undefined.
+ */
+bool QXmlQuery::evaluateTo(QStringList *target) const
+{
+ if(!target)
+ {
+ qWarning("A non-null callback must be passed.");
+ return false;
+ }
+
+ if(isValid())
+ {
+ try
+ {
+ /*
+ * This order is significant. expression() might cause
+ * query recompilation, and as part of that it recreates
+ * the static context. However, if we create the dynamic
+ * context before the query recompilation has been
+ * triggered, it will use the old static context, and
+ * hence old source locations.
+ */
+ const QPatternist::Expression::Ptr expr(d->expression());
+ if(!expr)
+ return false;
+
+ QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());
+
+ if(!QPatternist::BuiltinTypes::xsString->xdtTypeMatches(expr->staticType()->itemType()))
+ return false;
+
+ const QPatternist::Item::Iterator::Ptr it(expr->evaluateSequence(dynContext));
+ QPatternist::Item next(it->next());
+
+ while(!next.isNull())
+ {
+ target->append(next.stringValue());
+ next = it->next();
+ }
+
+ return true;
+ }
+ catch(const QPatternist::Exception)
+ {
+ return false;
+ }
+ }
+ else
+ return false;
+}
+
+/*!
+ Evaluates the query or stylesheet, and writes the output to \a target.
+
+ QXmlSerializer is used to write the output to \a target. In a future
+ release, it is expected that this function will be changed to
+ respect serialization options set in the stylesheet.
+
+ If an error occurs during the evaluation, error messages are sent to
+ messageHandler() and \c false is returned.
+
+ If \a target is \c null, or is not opened in at least
+ QIODevice::WriteOnly mode, the behavior is undefined. QXmlQuery
+ does not take ownership of \a target.
+
+ \since 4.5
+ \overload
+ */
+bool QXmlQuery::evaluateTo(QIODevice *target) const
+{
+ if(!target)
+ {
+ qWarning("The pointer to the device cannot be null.");
+ return false;
+ }
+
+ if(!target->isWritable())
+ {
+ qWarning("The device must be writable.");
+ return false;
+ }
+
+ QXmlSerializer serializer(*this, target);
+ return evaluateTo(&serializer);
+}
+
+/*!
+ Starts the evaluation and makes it available in \a result. If \a
+ result is null, the behavior is undefined. The evaluation takes
+ place incrementally (lazy evaluation), as the caller uses
+ QXmlResultItems::next() to get the next result.
+
+ \sa QXmlResultItems::next()
+*/
+void QXmlQuery::evaluateTo(QXmlResultItems *result) const
+{
+ if(!result)
+ {
+ qWarning("A null pointer cannot be passed.");
+ return;
+ }
+
+ if(isValid())
+ {
+ try
+ {
+ /*
+ * We don't have the d->expression() calls and
+ * d->dynamicContext() calls in the same order as seen in
+ * QXmlQuery::evaluateTo(), and the reason to why
+ * that isn't a problem, is that we call isValid().
+ */
+ const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());
+ result->d_ptr->setDynamicContext(dynContext);
+ result->d_ptr->iterator = d->expression()->evaluateSequence(dynContext);
+ }
+ catch(const QPatternist::Exception)
+ {
+ result->d_ptr->iterator = QPatternist::CommonValues::emptyIterator;
+ result->d_ptr->hasError = true;
+ }
+ }
+ else
+ {
+ result->d_ptr->iterator= QPatternist::CommonValues::emptyIterator;
+ result->d_ptr->hasError = true;
+ }
+}
+
+/*!
+ Evaluates the query, and serializes the output as XML to \a output.
+
+ If an error occurs during the evaluation, error messages are sent to
+ messageHandler(), the content of \a output is undefined and \c false is
+ returned, otherwise \c true is returned.
+
+ If \a output is \c null behavior is undefined. QXmlQuery
+ does not take ownership of \a output.
+
+ Internally, the class QXmlFormatter is used for this.
+ \since 4.5
+ */
+bool QXmlQuery::evaluateTo(QString *output) const
+{
+ Q_ASSERT_X(output, Q_FUNC_INFO,
+ "The input cannot be null");
+
+ QBuffer outputDevice;
+ outputDevice.open(QIODevice::ReadWrite);
+
+ QXmlFormatter formatter(*this, &outputDevice);
+ const bool success = evaluateTo(&formatter);
+
+ outputDevice.close();
+ *output = QString::fromUtf8(outputDevice.data().constData());
+
+ return success;
+}
+
+/*!
+ Returns true if this query is valid. Examples of invalid queries
+ are ones that contain syntax errors or that have not had setQuery()
+ called for them yet.
+ */
+bool QXmlQuery::isValid() const
+{
+ return d->isValid();
+}
+
+/*!
+ Sets the URI resolver to \a resolver. QXmlQuery does not take
+ ownership of \a resolver.
+
+ \sa uriResolver()
+ */
+void QXmlQuery::setUriResolver(const QAbstractUriResolver *resolver)
+{
+ d->uriResolver = resolver;
+}
+
+/*!
+ Returns the query's URI resolver. If no URI resolver has been set,
+ QtXmlPatterns will use the URIs in queries as they are.
+
+ The URI resolver provides a level of abstraction, or \e{polymorphic
+ URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
+ it can translate obsolete or invalid URIs to valid ones.
+
+ QtXmlPatterns calls the URI resolver for all URIs it encounters,
+ except for namespaces. Specifically, all builtin functions that deal
+ with URIs (\c{fn:doc()}, and \c{fn:doc-available()}).
+
+ In the case of \c{fn:doc()}, the absolute URI is the base URI in the
+ static context (which most likely is the location of the query).
+ Rather than use the URI the user specified, the return value of
+ QAbstractUriResolver::resolve() will be used.
+
+ When QtXmlPatterns calls QAbstractUriResolver::resolve() the
+ absolute URI is the URI mandated by the XQuery language, and the
+ relative URI is the URI specified by the user.
+
+ \sa setUriResolver()
+ */
+const QAbstractUriResolver *QXmlQuery::uriResolver() const
+{
+ return d->uriResolver;
+}
+
+/*!
+ Returns the name pool used by this QXmlQuery for constructing \l
+ {QXmlName} {names}. There is no setter for the name pool, because
+ mixing name pools causes errors due to name confusion.
+ */
+QXmlNamePool QXmlQuery::namePool() const
+{
+ return d->namePool;
+}
+
+/*!
+ Sets the focus to \a item. The focus is the set of items that the
+ context item expression and path expressions navigate from. For
+ example, in the expression \e p/span, the element that \e p
+ evaluates to is the focus for the following expression, \e span.
+
+ The focus can be accessed using the context item expression, i.e.,
+ dot (".").
+
+ By default, the focus is not set and is undefined. It will
+ therefore result in a dynamic error, \c XPDY0002, if the focus
+ is attempted to be accessed. The focus must be set before the
+ query is set with setQuery().
+
+ There is no behavior defined for setting an item which is null.
+
+ */
+void QXmlQuery::setFocus(const QXmlItem &item)
+{
+ d->contextItem = item;
+}
+
+/**
+ * This function should be a private member function of QXmlQuery,
+ * but we don't dare that due to our weird compilers.
+ * @internal
+ * @relates QXmlQuery
+ */
+template<typename TInputType>
+bool setFocusHelper(QXmlQuery *const queryInstance,
+ const TInputType &focusValue)
+{
+ /* We call resourceLoader(), so we have ensured that we have a resourceLoader
+ * that we will share in our copy. */
+ queryInstance->d->resourceLoader();
+
+ QXmlQuery focusQuery(*queryInstance);
+
+ /* Now we use the same, so we own the loaded document. */
+ focusQuery.d->m_resourceLoader = queryInstance->d->m_resourceLoader;
+
+ /* The copy constructor doesn't allow us to copy an existing QXmlQuery and
+ * changing the language at the same time so we need to use private API. */
+ focusQuery.d->queryLanguage = QXmlQuery::XQuery10;
+
+ Q_ASSERT(focusQuery.queryLanguage() == QXmlQuery::XQuery10);
+ focusQuery.bindVariable(QChar::fromLatin1('u'), focusValue);
+ focusQuery.setQuery(QLatin1String("doc($u)"));
+ Q_ASSERT(focusQuery.isValid());
+
+ QXmlResultItems focusResult;
+
+ queryInstance->d->m_resourceLoader = focusQuery.d->m_resourceLoader;
+
+ focusQuery.evaluateTo(&focusResult);
+ const QXmlItem focusItem(focusResult.next());
+
+ if(focusItem.isNull() || focusResult.hasError())
+ return false;
+ else
+ {
+ queryInstance->setFocus(focusItem);
+ return true;
+ }
+}
+
+/*!
+ \since 4.5
+ \overload
+
+ Sets the focus to be the document located at \a documentURI and
+ returns true. If \a documentURI cannot be loaded, false is returned.
+ It is undefined at what time the document may be loaded. When
+ loading the document, the message handler and URI resolver set on
+ this QXmlQuery are used.
+
+ If \a documentURI is empty or is not a valid URI, the behavior of
+ this function is undefined.
+ */
+bool QXmlQuery::setFocus(const QUrl &documentURI)
+{
+ Q_ASSERT_X(documentURI.isValid() && !documentURI.isEmpty(),
+ Q_FUNC_INFO,
+ "The URI passed must be valid.");
+
+ return setFocusHelper(this, QVariant(documentURI));
+}
+
+/*!
+
+ Sets the focus to be the \a document read from the QIODevice and
+ returns true. If \a document cannot be loaded, false is returned.
+
+ QXmlQuery does not take ownership of \a document. The user
+ guarantees that a document is available from the \a document device
+ and that the document is not empty. The device must be opened in at
+ least read-only mode. \a document must stay in scope as long as the
+ current query is active.
+
+ \since 4.5
+ \overload
+ */
+bool QXmlQuery::setFocus(QIODevice *document)
+{
+ if(!document)
+ {
+ qWarning("A null QIODevice pointer cannot be passed.");
+ return false;
+ }
+
+ if(!document->isReadable())
+ {
+ qWarning("The device must be readable.");
+ return false;
+ }
+
+ return setFocusHelper(this, document);
+}
+
+/*!
+ This function behaves identically to calling the setFocus() overload with a
+ QIODevice whose content is \a focus encoded as UTF-8. That is, \a focus is
+ treated as if it contained an XML document.
+
+ Returns the same result as the overload.
+
+ \overload
+ \since 4.6
+ */
+bool QXmlQuery::setFocus(const QString &focus)
+{
+ QBuffer device;
+ device.setData(focus.toUtf8());
+ device.open(QIODevice::ReadOnly);
+
+ return setFocusHelper(this, &device);
+}
+
+/*!
+ Returns a value indicating what this QXmlQuery is being used for.
+ The default is QXmlQuery::XQuery10, which means the QXmlQuery is
+ being used for running XQuery and XPath queries. QXmlQuery::XSLT20
+ can also be returned, which indicates the QXmlQuery is for running
+ XSL-T spreadsheets.
+
+ \since 4.5
+ */
+QXmlQuery::QueryLanguage QXmlQuery::queryLanguage() const
+{
+ return d->queryLanguage;
+}
+
+/*!
+ Sets the \a name of the initial template. The initial template is
+ the one the processor calls first, instead of attempting to match a
+ template to the context node (if any). If an initial template is not
+ set, the standard order of template invocation will be used.
+
+ This function only applies when using QXmlQuery to process XSL-T
+ stylesheets. The name becomes part of the compiled stylesheet.
+ Therefore, this function must be called before calling setQuery().
+
+ If the stylesheet has no template named \a name, the processor will
+ use the standard order of template invocation.
+
+ \since 4.5
+ \sa initialTemplateName()
+ */
+void QXmlQuery::setInitialTemplateName(const QXmlName &name)
+{
+ d->initialTemplateName = name;
+}
+
+/*!
+ \overload
+
+ Sets the name of the initial template to \a localName, which must be
+ a valid \l{QXmlName::localName()} {local name}. The initial template
+ is the one the processor calls first, instead of attempting to match
+ a template to the context node (if any). If an initial template is
+ not set, the standard order of template invocation will be used.
+
+ This function only applies when using QXmlQuery to process XSL-T
+ stylesheets. The name becomes part of the compiled stylesheet.
+ Therefore, this function must be called before calling setQuery().
+
+ If \a localName is not a valid \l{QXmlName::localName()} {local
+ name}, the effect is undefined. If the stylesheet has no template
+ named \a localName, the processor will use the standard order of
+ template invocation.
+
+ \since 4.5
+ \sa initialTemplateName()
+ */
+void QXmlQuery::setInitialTemplateName(const QString &localName)
+{
+ Q_ASSERT_X(QXmlName::isNCName(localName),
+ Q_FUNC_INFO,
+ "The name passed must be a valid NCName.");
+ setInitialTemplateName(QXmlName(d->namePool, localName));
+}
+
+/*!
+ Returns the name of the XSL-T stylesheet template that the processor
+ will call first when running an XSL-T stylesheet. This function only
+ applies when using QXmlQuery to process XSL-T stylesheets. By
+ default, no initial template is set. In that case, a default
+ constructed QXmlName is returned.
+
+ \since 4.5
+ */
+QXmlName QXmlQuery::initialTemplateName() const
+{
+ return d->initialTemplateName;
+}
+
+/*!
+ Sets the network manager to \a newManager.
+ QXmlQuery does not take ownership of \a newManager.
+
+ \sa networkAccessManager()
+ \since 4.5
+ */
+void QXmlQuery::setNetworkAccessManager(QNetworkAccessManager *newManager)
+{
+ d->m_networkAccessDelegator->m_genericManager = newManager;
+}
+
+/*!
+ Returns the network manager, or 0 if it has not been set.
+
+ \sa setNetworkAccessManager()
+ \since 4.5
+ */
+QNetworkAccessManager *QXmlQuery::networkAccessManager() const
+{
+ return d->m_networkAccessDelegator->m_genericManager;
+}
+
+/*!
+ Binds the result of the query \a query, to a variable by name \a name.
+
+ Evaluation of \a query will be commenced when this function is called.
+
+ If \a query is invalid, behavior is undefined. \a query will be copied.
+
+ \since 4.5
+ \sa isValid()
+ */
+void QXmlQuery::bindVariable(const QXmlName &name, const QXmlQuery &query)
+{
+ Q_ASSERT_X(query.isValid(), Q_FUNC_INFO, "The query being bound must be valid.");
+
+ const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
+ const QVariant variant(QVariant::fromValue(query));
+
+ if(vl->invalidationRequired(name, variant))
+ d->recompileRequired();
+
+ vl->addBinding(name, variant);
+}
+
+/*!
+ \overload
+
+ Has the same behavior and effects as the function being overloaded, but takes
+ the variable name \a localName as a QString. \a query is used as in the
+ overloaded function.
+
+ \since 4.5
+ */
+void QXmlQuery::bindVariable(const QString &localName, const QXmlQuery &query)
+{
+ return bindVariable(QXmlName(d->namePool, localName), query);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qxmlquery.h b/src/xmlpatterns/api/qxmlquery.h
new file mode 100644
index 0000000..041d035
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlquery.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLQUERY_H
+#define QXMLQUERY_H
+
+#include <QtCore/QUrl>
+#include <QtXmlPatterns/QAbstractXmlNodeModel>
+#include <QtXmlPatterns/QAbstractXmlReceiver>
+#include <QtXmlPatterns/QXmlNamePool>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QAbstractMessageHandler;
+class QAbstractUriResolver;
+class QIODevice;
+class QNetworkAccessManager;
+class QXmlName;
+class QXmlNodeIndex;
+class QXmlQueryPrivate;
+class QXmlResultItems;
+class QXmlSerializer;
+
+/* The members in the namespace QPatternistSDK are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+namespace QPatternistSDK
+{
+ class TestCase;
+}
+
+namespace QPatternist
+{
+ class XsdSchemaParser;
+ class XsdValidatingInstanceReader;
+ class VariableLoader;
+}
+
+class Q_XMLPATTERNS_EXPORT QXmlQuery
+{
+public:
+ enum QueryLanguage
+ {
+ XQuery10 = 1,
+ XSLT20 = 2,
+ XmlSchema11IdentityConstraintSelector = 1024,
+ XmlSchema11IdentityConstraintField = 2048,
+ XPath20 = 4096
+ };
+
+ QXmlQuery();
+ QXmlQuery(const QXmlQuery &other);
+ QXmlQuery(const QXmlNamePool &np);
+ QXmlQuery(QueryLanguage queryLanguage,
+ const QXmlNamePool &np = QXmlNamePool());
+ ~QXmlQuery();
+ QXmlQuery &operator=(const QXmlQuery &other);
+
+ void setMessageHandler(QAbstractMessageHandler *messageHandler);
+ QAbstractMessageHandler *messageHandler() const;
+
+ void setQuery(const QString &sourceCode, const QUrl &documentURI = QUrl());
+ void setQuery(QIODevice *sourceCode, const QUrl &documentURI = QUrl());
+ void setQuery(const QUrl &queryURI, const QUrl &baseURI = QUrl());
+
+ QXmlNamePool namePool() const;
+
+ void bindVariable(const QXmlName &name, const QXmlItem &value);
+ void bindVariable(const QString &localName, const QXmlItem &value);
+
+ void bindVariable(const QXmlName &name, QIODevice *);
+ void bindVariable(const QString &localName, QIODevice *);
+ void bindVariable(const QXmlName &name, const QXmlQuery &query);
+ void bindVariable(const QString &localName, const QXmlQuery &query);
+
+ bool isValid() const;
+
+ void evaluateTo(QXmlResultItems *result) const;
+ bool evaluateTo(QAbstractXmlReceiver *callback) const;
+ bool evaluateTo(QStringList *target) const;
+ bool evaluateTo(QIODevice *target) const;
+ bool evaluateTo(QString *output) const;
+
+ void setUriResolver(const QAbstractUriResolver *resolver);
+ const QAbstractUriResolver *uriResolver() const;
+
+ void setFocus(const QXmlItem &item);
+ bool setFocus(const QUrl &documentURI);
+ bool setFocus(QIODevice *document);
+ bool setFocus(const QString &focus);
+
+ void setInitialTemplateName(const QXmlName &name);
+ void setInitialTemplateName(const QString &name);
+ QXmlName initialTemplateName() const;
+
+ void setNetworkAccessManager(QNetworkAccessManager *newManager);
+ QNetworkAccessManager *networkAccessManager() const;
+
+ QueryLanguage queryLanguage() const;
+private:
+ friend class QXmlName;
+ friend class QXmlSerializer;
+ friend class QPatternistSDK::TestCase;
+ friend class QPatternist::XsdSchemaParser;
+ friend class QPatternist::XsdValidatingInstanceReader;
+ friend class QPatternist::VariableLoader;
+ template<typename TInputType> friend bool setFocusHelper(QXmlQuery *const queryInstance,
+ const TInputType &focusValue);
+ QXmlQueryPrivate *d;
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlquery_p.h b/src/xmlpatterns/api/qxmlquery_p.h
new file mode 100644
index 0000000..629b50b
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlquery_p.h
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QXMLQUERY_P_H
+#define QXMLQUERY_P_H
+
+#include <QAbstractMessageHandler>
+#include <QAbstractUriResolver>
+#include <QPointer>
+#include <QSourceLocation>
+#include <QUrl>
+#include <QVariant>
+#include <QXmlName>
+#include <QXmlNamePool>
+#include <QXmlQuery>
+
+#include "qacceltreebuilder_p.h"
+#include "qacceltreeresourceloader_p.h"
+#include "qcoloringmessagehandler_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qexpressionfactory_p.h"
+#include "qfocus_p.h"
+#include "qfunctionfactorycollection_p.h"
+#include "qgenericdynamiccontext_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qnamepool_p.h"
+#include "qnetworkaccessdelegator_p.h"
+#include "qreferencecountedvalue_p.h"
+#include "qresourcedelegator_p.h"
+#include "qstaticfocuscontext_p.h"
+#include "quriloader_p.h"
+#include "qvariableloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXmlQueryPrivate
+{
+public:
+
+ inline QXmlQueryPrivate(const QXmlNamePool &np = QXmlNamePool()) : namePool(np)
+ , messageHandler(0)
+ , uriResolver(0)
+ , queryLanguage(QXmlQuery::XQuery10)
+ , m_networkAccessDelegator(new QPatternist::NetworkAccessDelegator(0, 0))
+ {
+ m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, variableLoader());
+ }
+
+ void detach()
+ {
+ if(m_variableLoader)
+ m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d, m_variableLoader));
+
+ delete m_networkAccessDelegator->m_variableURIManager;
+ m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, m_variableLoader);
+
+ if(m_resourceLoader)
+ {
+ const QPatternist::AccelTreeResourceLoader::Ptr nev(new QPatternist::AccelTreeResourceLoader(namePool.d,
+ m_networkAccessDelegator));
+ m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::ResourceDelegator(m_resourceLoader->deviceURIs(),
+ m_resourceLoader,
+ nev));
+ }
+ }
+
+ bool isValid()
+ {
+ return expression();
+ }
+
+ inline void recompileRequired()
+ {
+ m_expr.reset();
+ }
+
+ inline QPatternist::VariableLoader::Ptr variableLoader()
+ {
+ if(!m_variableLoader)
+ m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d));
+
+ return m_variableLoader;
+ }
+
+ inline QPatternist::GenericStaticContext::Ptr staticContext()
+ {
+ if(m_staticContext && m_expr)
+ return m_staticContext;
+ /* Else, re-create the staticContext. */
+
+ if(!messageHandler)
+ messageHandler = new QPatternist::ColoringMessageHandler(ownerObject());
+
+ if(!m_functionFactory)
+ {
+ if(queryLanguage == QXmlQuery::XSLT20)
+ m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(namePool.d);
+ else
+ m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d);
+ }
+
+ const QPatternist::GenericStaticContext::Ptr genericStaticContext(new QPatternist::GenericStaticContext(namePool.d,
+ messageHandler,
+ queryURI,
+ m_functionFactory,
+ queryLanguage));
+ genericStaticContext->setResourceLoader(resourceLoader());
+
+ genericStaticContext->setExternalVariableLoader(variableLoader());
+
+ m_staticContext = genericStaticContext;
+
+ if(!contextItem.isNull())
+ m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::AtomicValue::qtToXDMType(contextItem), m_staticContext));
+ else if( queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField
+ || queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintSelector
+ || queryLanguage == QXmlQuery::XPath20)
+ m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::BuiltinTypes::node, m_staticContext));
+
+ for (int i = 0; i < m_additionalNamespaceBindings.count(); ++i) {
+ m_staticContext->namespaceBindings()->addBinding(m_additionalNamespaceBindings.at(i));
+ }
+
+ return m_staticContext;
+ }
+
+ inline QPatternist::DynamicContext::Ptr dynamicContext(QAbstractXmlReceiver *const callback = 0)
+ {
+ const QPatternist::StaticContext::Ptr statContext(staticContext());
+ Q_ASSERT(statContext);
+
+ QPatternist::GenericDynamicContext::Ptr dynContext(new QPatternist::GenericDynamicContext(namePool.d, statContext->messageHandler(),
+ statContext->sourceLocations()));
+
+ QPatternist::AutoPtr<QPatternist::NodeBuilder> nodeBuilder(new QPatternist::AccelTreeBuilder<false>(QUrl(), QUrl(), namePool.d,
+ dynContext.data()));
+ dynContext->setNodeBuilder(nodeBuilder);
+
+ dynContext->setResourceLoader(statContext->resourceLoader());
+ dynContext->setExternalVariableLoader(statContext->externalVariableLoader());
+ dynContext->setUriResolver(uriResolver);
+
+ if(callback)
+ dynContext->setOutputReceiver(callback);
+
+ if(contextItem.isNull())
+ return dynContext;
+ else
+ {
+ QPatternist::DynamicContext::Ptr focus(new QPatternist::Focus(dynContext));
+ QPatternist::Item::Iterator::Ptr it(QPatternist::makeSingletonIterator(QPatternist::Item::fromPublic(contextItem)));
+ it->next();
+ focus->setFocusIterator(it);
+ return focus;
+ }
+ }
+
+ inline QPatternist::AccelTreeResourceLoader::Ptr resourceLoader()
+ {
+ if(!m_resourceLoader)
+ m_resourceLoader = (new QPatternist::AccelTreeResourceLoader(namePool.d, m_networkAccessDelegator));
+
+ return m_resourceLoader;
+ }
+
+ void setRequiredType(const QPatternist::SequenceType::Ptr &seqType)
+ {
+ Q_ASSERT(seqType);
+ if(!m_requiredType || m_requiredType->is(seqType))
+ return;
+
+ m_requiredType = seqType;
+ m_staticContext.reset();
+ }
+
+ QPatternist::SequenceType::Ptr requiredType()
+ {
+ if(m_requiredType)
+ return m_requiredType;
+ else
+ {
+ m_requiredType = QPatternist::CommonSequenceTypes::ZeroOrMoreItems;
+ return m_requiredType;
+ }
+ }
+
+ QPatternist::Expression::Ptr expression(QIODevice *const queryDevice = 0)
+ {
+ if(m_expr && !queryDevice)
+ return m_expr;
+
+ /* If we need to update, but we don't have any source code, we can
+ * never create an Expression. */
+ if(!queryDevice)
+ return QPatternist::Expression::Ptr();
+
+ try
+ {
+ /* The static context has source locations, and they need to be
+ * updated to the new query. */
+ m_staticContext.reset();
+
+ if(!m_expressionFactory)
+ m_expressionFactory = QPatternist::ExpressionFactory::Ptr(new QPatternist::ExpressionFactory());
+
+ m_expr = m_expressionFactory->createExpression(queryDevice, staticContext(),
+ queryLanguage,
+ requiredType(),
+ queryURI,
+ initialTemplateName);
+ }
+ catch(const QPatternist::Exception)
+ {
+ m_expr.reset();
+
+ /* We don't call m_staticContext.reset() because it shouldn't be
+ * necessary, since m_staticContext is changed when the expression
+ * is changed. */
+ }
+
+ return m_expr;
+ }
+
+ inline void addAdditionalNamespaceBinding(const QXmlName &binding)
+ {
+ m_additionalNamespaceBindings.append(binding);
+ }
+
+ QXmlNamePool namePool;
+ QPointer<QAbstractMessageHandler> messageHandler;
+ /**
+ * Must be absolute and valid.
+ */
+ QUrl queryURI;
+ const QAbstractUriResolver * uriResolver;
+ QXmlItem contextItem;
+ QXmlName initialTemplateName;
+
+ inline void setExpressionFactory(const QPatternist::ExpressionFactory::Ptr &expr)
+ {
+ m_expressionFactory = expr;
+ }
+
+ QXmlQuery::QueryLanguage queryLanguage;
+ QPointer<QNetworkAccessManager> userNetworkManager;
+
+ inline QObject *ownerObject()
+ {
+ if(!m_owner)
+ m_owner = new QPatternist::ReferenceCountedValue<QObject>(new QObject());
+
+ return m_owner->value;
+ }
+
+ QPatternist::ExpressionFactory::Ptr m_expressionFactory;
+ QPatternist::StaticContext::Ptr m_staticContext;
+ QPatternist::VariableLoader::Ptr m_variableLoader;
+ QPatternist::DeviceResourceLoader::Ptr m_resourceLoader;
+ /**
+ * This is the AST for the query.
+ */
+ QPatternist::Expression::Ptr m_expr;
+ QPatternist::ReferenceCountedValue<QObject>::Ptr m_owner;
+
+ /**
+ * This is our effective network manager, that we end up using. The one the
+ * user sets is userNetworkManager.
+ */
+ QPatternist::SequenceType::Ptr m_requiredType;
+ QPatternist::FunctionFactory::Ptr m_functionFactory;
+ QPatternist::NetworkAccessDelegator::Ptr m_networkAccessDelegator;
+
+ QList<QXmlName> m_additionalNamespaceBindings;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlresultitems.cpp b/src/xmlpatterns/api/qxmlresultitems.cpp
new file mode 100644
index 0000000..4d167d0
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlresultitems.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxmlresultitems.h"
+#include "qxmlresultitems_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QXmlResultItems
+ \brief The QXmlResultItems class iterates through the results of evaluating an XQuery in QXmlQuery.
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ QXmlResultItems presents the evaluation of an associated query as a
+ sequence of \l{QXmlItem}{QXmlItems}. The sequence is traversed by
+ repeatedly calling next(), which actually produces the sequence by
+ lazy evaluation of the query.
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp 0
+
+ An effect of letting next() produce the sequence by lazy evaluation
+ is that a query error can occur on any call to next(). If an error
+ occurs, both next() and current() will return the null QXmlItem, and
+ hasError() will return true.
+
+ QXmlResultItems can be thought of as an "iterator" that traverses
+ the sequence of query results once, in the forward direction. Each
+ call to next() advances the iterator to the next QXmlItem in the
+ sequence and returns it, and current() always returns the QXmlItem
+ that next() returned the last time it was called.
+
+ \note When using the QXmlResultItems overload of QXmlQuery::evaluateTo()
+ to execute a query, it is advisable to create a new instance of this
+ class for each new set of results rather than reusing an old instance.
+
+ \sa QXmlItem::isNode(), QXmlItem::isAtomicValue(), QXmlNodeModelIndex
+ */
+
+/*!
+ Constructs an instance of QXmlResultItems.
+ */
+QXmlResultItems::QXmlResultItems() : d_ptr(new QXmlResultItemsPrivate())
+{
+}
+
+/*!
+ Destroys this instance of QXmlResultItems.
+ */
+QXmlResultItems::~QXmlResultItems()
+{
+}
+
+/*!
+ Returns the next result in the sequence produced by lazy evaluation
+ of the associated query. When the returned QXmlItem is null, either
+ the evaluation terminated normally without producing another result,
+ or an error occurred. Call hasError() to determine whether the null
+ item was caused by normal termination or by an error.
+
+ Returns a null QXmlItem if there is no associated QXmlQuery.
+ */
+QXmlItem QXmlResultItems::next()
+{
+ Q_D(QXmlResultItems);
+ if(d->hasError)
+ return QXmlItem();
+
+ try
+ {
+ d->current = QPatternist::Item::toPublic(d->iterator->next());
+ return d->current;
+ }
+ catch(const QPatternist::Exception)
+ {
+ d->current = QXmlItem();
+ d->hasError = true;
+ return QXmlItem();
+ }
+}
+
+/*!
+ Returns the current item. The current item is the last item
+ that was produced and returned by next().
+
+ Returns a null QXmlItem if there is no associated QXmlQuery.
+ */
+QXmlItem QXmlResultItems::current() const
+{
+ Q_D(const QXmlResultItems);
+
+ if(d->hasError)
+ return QXmlItem();
+ else
+ return d->current;
+}
+
+/*!
+
+ If an error occurred during evaluation of the query, true is
+ returned.
+
+ Returns false if query evaluation has been done.
+ */
+bool QXmlResultItems::hasError() const
+{
+ Q_D(const QXmlResultItems);
+ return d->hasError;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/api/qxmlresultitems.h b/src/xmlpatterns/api/qxmlresultitems.h
new file mode 100644
index 0000000..0a12048
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlresultitems.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLRESULTITEMS
+#define QXMLRESULTITEMS
+
+#include <QtCore/QString>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QXmlItem;
+class QXmlQuery;
+class QXmlResultItemsPrivate;
+
+class Q_XMLPATTERNS_EXPORT QXmlResultItems
+{
+public:
+ QXmlResultItems();
+ virtual ~QXmlResultItems();
+
+ bool hasError() const;
+ QXmlItem next();
+ QXmlItem current() const;
+
+private:
+ friend class QXmlQuery;
+ Q_DECLARE_PRIVATE(QXmlResultItems)
+ QScopedPointer<QXmlResultItemsPrivate> d_ptr;
+ Q_DISABLE_COPY(QXmlResultItems)
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlresultitems_p.h b/src/xmlpatterns/api/qxmlresultitems_p.h
new file mode 100644
index 0000000..3d0a0e9
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlresultitems_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QXMLRESULTITEMS_P_H
+#define QXMLRESULTITEMS_P_H
+
+#include "qcommonvalues_p.h"
+#include "qdynamiccontext_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXmlResultItemsPrivate
+{
+public:
+ inline QXmlResultItemsPrivate() : iterator(QPatternist::CommonValues::emptyIterator)
+ , hasError(false)
+ {
+ }
+
+ void setDynamicContext(const QPatternist::DynamicContext::Ptr &context)
+ {
+ m_context = context;
+ }
+
+ QPatternist::Item::Iterator::Ptr iterator;
+ QXmlItem current;
+ bool hasError;
+private:
+ /**
+ * We never use it. We only keep a ref to it such that it doesn't get
+ * de-allocated.
+ */
+ QPatternist::DynamicContext::Ptr m_context;
+};
+
+QT_END_NAMESPACE
+#endif
+
diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp
new file mode 100644
index 0000000..ee92195
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+
+#include <QtCore/QIODevice>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QXmlSchema
+
+ \brief The QXmlSchema class provides loading and validation of a W3C XML Schema.
+
+ \reentrant
+ \since 4.6
+ \ingroup xml-tools
+
+ The QXmlSchema class loads, compiles and validates W3C XML Schema files
+ that can be used further for validation of XML instance documents via
+ \l{QXmlSchemaValidator}.
+
+ The following example shows how to load a XML Schema file from the network
+ and test whether it is a valid schema document:
+
+ \snippet doc/src/snippets/qxmlschema/main.cpp 0
+
+ \section1 XML Schema Version
+
+ This class is used to represent schemas that conform to the \l{XML Schema} 1.0
+ specification.
+
+ \sa QXmlSchemaValidator, {xmlpatterns/schema}{XML Schema Validation Example}
+*/
+
+/*!
+ Constructs an invalid, empty schema that cannot be used until
+ load() is called.
+ */
+QXmlSchema::QXmlSchema()
+ : d(new QXmlSchemaPrivate(QXmlNamePool()))
+{
+}
+
+/*!
+ Constructs a QXmlSchema that is a copy of \a other. The new
+ instance will share resources with the existing schema
+ to the extent possible.
+ */
+QXmlSchema::QXmlSchema(const QXmlSchema &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Destroys this QXmlSchema.
+ */
+QXmlSchema::~QXmlSchema()
+{
+}
+
+/*!
+ Sets this QXmlSchema to a schema loaded from the \a source
+ URI.
+
+ If the schema \l {isValid()} {is invalid}, \c{false} is returned
+ and the behavior is undefined.
+
+ Example:
+
+ \snippet doc/src/snippets/qxmlschema/main.cpp 0
+
+ \sa isValid()
+ */
+bool QXmlSchema::load(const QUrl &source)
+{
+ d->load(source, QString());
+ return d->isValid();
+}
+
+/*!
+ Sets this QXmlSchema to a schema read from the \a source
+ device. The device must have been opened with at least
+ QIODevice::ReadOnly.
+
+ \a documentUri represents the schema obtained from the \a source
+ device. It is the base URI of the schema, that is used
+ internally to resolve relative URIs that appear in the schema, and
+ for message reporting.
+
+ If \a source is \c null or not readable, or if \a documentUri is not
+ a valid URI, behavior is undefined.
+
+ If the schema \l {isValid()} {is invalid}, \c{false} is returned
+ and the behavior is undefined.
+
+ Example:
+
+ \snippet doc/src/snippets/qxmlschema/main.cpp 1
+
+ \sa isValid()
+ */
+bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri)
+{
+ d->load(source, documentUri, QString());
+ return d->isValid();
+}
+
+/*!
+ Sets this QXmlSchema to a schema read from the \a data
+
+ \a documentUri represents the schema obtained from the \a data.
+ It is the base URI of the schema, that is used internally to
+ resolve relative URIs that appear in the schema, and
+ for message reporting.
+
+ If \a documentUri is not a valid URI, behavior is undefined.
+ \sa isValid()
+
+ If the schema \l {isValid()} {is invalid}, \c{false} is returned
+ and the behavior is undefined.
+
+ Example:
+
+ \snippet doc/src/snippets/qxmlschema/main.cpp 2
+
+ \sa isValid()
+ */
+bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri)
+{
+ d->load(data, documentUri, QString());
+ return d->isValid();
+}
+
+/*!
+ Returns true if this schema is valid. Examples of invalid schemas
+ are ones that contain syntax errors or that do not conform the
+ W3C XML Schema specification.
+ */
+bool QXmlSchema::isValid() const
+{
+ return d->isValid();
+}
+
+/*!
+ Returns the name pool used by this QXmlSchema for constructing \l
+ {QXmlName} {names}. There is no setter for the name pool, because
+ mixing name pools causes errors due to name confusion.
+ */
+QXmlNamePool QXmlSchema::namePool() const
+{
+ return d->namePool();
+}
+
+/*!
+ Returns the document URI of the schema or an empty URI if no
+ schema has been set.
+ */
+QUrl QXmlSchema::documentUri() const
+{
+ return d->documentUri();
+}
+
+/*!
+ Changes the \l {QAbstractMessageHandler}{message handler} for this
+ QXmlSchema to \a handler. The schema sends all compile and
+ validation messages to this message handler. QXmlSchema does not take
+ ownership of \a handler.
+
+ Normally, the default message handler is sufficient. It writes
+ compile and validation messages to \e stderr. The default message
+ handler includes color codes if \e stderr can render colors.
+
+ When QXmlSchema calls QAbstractMessageHandler::message(),
+ the arguments are as follows:
+
+ \table
+ \header
+ \o message() argument
+ \o Semantics
+ \row
+ \o QtMsgType type
+ \o Only QtWarningMsg and QtFatalMsg are used. The former
+ identifies a warning, while the latter identifies an error.
+ \row
+ \o const QString & description
+ \o An XHTML document which is the actual message. It is translated
+ into the current language.
+ \row
+ \o const QUrl &identifier
+ \o Identifies the error with a URI, where the fragment is
+ the error code, and the rest of the URI is the error namespace.
+ \row
+ \o const QSourceLocation & sourceLocation
+ \o Identifies where the error occurred.
+ \endtable
+
+ */
+void QXmlSchema::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ d->setMessageHandler(handler);
+}
+
+/*!
+ Returns the message handler that handles compile and validation
+ messages for this QXmlSchema.
+ */
+QAbstractMessageHandler *QXmlSchema::messageHandler() const
+{
+ return d->messageHandler();
+}
+
+/*!
+ Sets the URI resolver to \a resolver. QXmlSchema does not take
+ ownership of \a resolver.
+
+ \sa uriResolver()
+ */
+void QXmlSchema::setUriResolver(const QAbstractUriResolver *resolver)
+{
+ d->setUriResolver(resolver);
+}
+
+/*!
+ Returns the schema's URI resolver. If no URI resolver has been set,
+ QtXmlPatterns will use the URIs in schemas as they are.
+
+ The URI resolver provides a level of abstraction, or \e{polymorphic
+ URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
+ it can translate obsolete or invalid URIs to valid ones.
+
+ When QtXmlPatterns calls QAbstractUriResolver::resolve() the
+ absolute URI is the URI mandated by the schema specification, and the
+ relative URI is the URI specified by the user.
+
+ \sa setUriResolver()
+ */
+const QAbstractUriResolver *QXmlSchema::uriResolver() const
+{
+ return d->uriResolver();
+}
+
+/*!
+ Sets the network manager to \a manager.
+ QXmlSchema does not take ownership of \a manager.
+
+ \sa networkAccessManager()
+ */
+void QXmlSchema::setNetworkAccessManager(QNetworkAccessManager *manager)
+{
+ d->setNetworkAccessManager(manager);
+}
+
+/*!
+ Returns the network manager, or 0 if it has not been set.
+
+ \sa setNetworkAccessManager()
+ */
+QNetworkAccessManager *QXmlSchema::networkAccessManager() const
+{
+ return d->networkAccessManager();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h
new file mode 100644
index 0000000..145f2dc
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLSCHEMA_H
+#define QXMLSCHEMA_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QUrl>
+#include <QtXmlPatterns/QXmlNamePool>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QAbstractMessageHandler;
+class QAbstractUriResolver;
+class QIODevice;
+class QNetworkAccessManager;
+class QUrl;
+class QXmlNamePool;
+class QXmlSchemaPrivate;
+
+class Q_XMLPATTERNS_EXPORT QXmlSchema
+{
+ friend class QXmlSchemaValidatorPrivate;
+
+ public:
+ QXmlSchema();
+ QXmlSchema(const QXmlSchema &other);
+ ~QXmlSchema();
+
+ bool load(const QUrl &source);
+ bool load(QIODevice *source, const QUrl &documentUri = QUrl());
+ bool load(const QByteArray &data, const QUrl &documentUri = QUrl());
+
+ bool isValid() const;
+
+ QXmlNamePool namePool() const;
+ QUrl documentUri() const;
+
+ void setMessageHandler(QAbstractMessageHandler *handler);
+ QAbstractMessageHandler *messageHandler() const;
+
+ void setUriResolver(const QAbstractUriResolver *resolver);
+ const QAbstractUriResolver *uriResolver() const;
+
+ void setNetworkAccessManager(QNetworkAccessManager *networkmanager);
+ QNetworkAccessManager *networkAccessManager() const;
+
+ private:
+ QSharedDataPointer<QXmlSchemaPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp
new file mode 100644
index 0000000..f5ed5c0
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema_p.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qacceltreeresourceloader_p.h"
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+
+#include <QtCore/QBuffer>
+#include <QtCore/QIODevice>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlNamePool &namePool)
+ : m_namePool(namePool)
+ , m_userMessageHandler(0)
+ , m_uriResolver(0)
+ , m_userNetworkAccessManager(0)
+ , m_schemaContext(new QPatternist::XsdSchemaContext(m_namePool.d))
+ , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext))
+ , m_schemaIsValid(false)
+{
+ m_networkAccessManager = new QPatternist::ReferenceCountedValue<QNetworkAccessManager>(new QNetworkAccessManager());
+ m_messageHandler = new QPatternist::ReferenceCountedValue<QAbstractMessageHandler>(new QPatternist::ColoringMessageHandler());
+}
+
+QXmlSchemaPrivate::QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext)
+ : m_namePool(QXmlNamePool(schemaContext->namePool().data()))
+ , m_userMessageHandler(0)
+ , m_uriResolver(0)
+ , m_userNetworkAccessManager(0)
+ , m_schemaContext(schemaContext)
+ , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext))
+ , m_schemaIsValid(false)
+{
+ m_networkAccessManager = new QPatternist::ReferenceCountedValue<QNetworkAccessManager>(new QNetworkAccessManager());
+ m_messageHandler = new QPatternist::ReferenceCountedValue<QAbstractMessageHandler>(new QPatternist::ColoringMessageHandler());
+}
+
+QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlSchemaPrivate &other)
+ : QSharedData(other)
+{
+ m_namePool = other.m_namePool;
+ m_userMessageHandler = other.m_userMessageHandler;
+ m_uriResolver = other.m_uriResolver;
+ m_userNetworkAccessManager = other.m_userNetworkAccessManager;
+ m_messageHandler = other.m_messageHandler;
+ m_networkAccessManager = other.m_networkAccessManager;
+
+ m_schemaContext = other.m_schemaContext;
+ m_schemaParserContext = other.m_schemaParserContext;
+ m_schemaIsValid = other.m_schemaIsValid;
+ m_documentUri = other.m_documentUri;
+}
+
+void QXmlSchemaPrivate::load(const QUrl &source, const QString &targetNamespace)
+{
+ m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(source);
+
+ m_schemaContext->setMessageHandler(messageHandler());
+ m_schemaContext->setUriResolver(uriResolver());
+ m_schemaContext->setNetworkAccessManager(networkAccessManager());
+
+ const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, m_schemaContext->networkAccessManager(),
+ m_schemaContext, QPatternist::AccelTreeResourceLoader::ContinueOnError));
+ if (reply)
+ load(reply.data(), source, targetNamespace);
+}
+
+void QXmlSchemaPrivate::load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace)
+{
+ QByteArray localData(data);
+
+ QBuffer buffer(&localData);
+ buffer.open(QIODevice::ReadOnly);
+
+ load(&buffer, documentUri, targetNamespace);
+}
+
+void QXmlSchemaPrivate::load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace)
+{
+ m_schemaParserContext = QPatternist::XsdSchemaParserContext::Ptr(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext));
+ m_schemaIsValid = false;
+
+ if (!source) {
+ qWarning("A null QIODevice pointer cannot be passed.");
+ return;
+ }
+
+ if (!source->isReadable()) {
+ qWarning("The device must be readable.");
+ return;
+ }
+
+ m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri);
+ m_schemaContext->setMessageHandler(messageHandler());
+ m_schemaContext->setUriResolver(uriResolver());
+ m_schemaContext->setNetworkAccessManager(networkAccessManager());
+
+ QPatternist::XsdSchemaParser parser(m_schemaContext, m_schemaParserContext, source);
+ parser.setDocumentURI(documentUri);
+ parser.setTargetNamespace(targetNamespace);
+
+ try {
+ parser.parse();
+ m_schemaParserContext->resolver()->resolve();
+
+ m_schemaIsValid = true;
+ } catch (QPatternist::Exception exception) {
+ m_schemaIsValid = false;
+ }
+}
+
+bool QXmlSchemaPrivate::isValid() const
+{
+ return m_schemaIsValid;
+}
+
+QXmlNamePool QXmlSchemaPrivate::namePool() const
+{
+ return m_namePool;
+}
+
+QUrl QXmlSchemaPrivate::documentUri() const
+{
+ return m_documentUri;
+}
+
+void QXmlSchemaPrivate::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ m_userMessageHandler = handler;
+}
+
+QAbstractMessageHandler *QXmlSchemaPrivate::messageHandler() const
+{
+ if (m_userMessageHandler)
+ return m_userMessageHandler;
+
+ return m_messageHandler.data()->value;
+}
+
+void QXmlSchemaPrivate::setUriResolver(const QAbstractUriResolver *resolver)
+{
+ m_uriResolver = resolver;
+}
+
+const QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const
+{
+ return m_uriResolver;
+}
+
+void QXmlSchemaPrivate::setNetworkAccessManager(QNetworkAccessManager *networkmanager)
+{
+ m_userNetworkAccessManager = networkmanager;
+}
+
+QNetworkAccessManager *QXmlSchemaPrivate::networkAccessManager() const
+{
+ if (m_userNetworkAccessManager)
+ return m_userNetworkAccessManager;
+
+ return m_networkAccessManager.data()->value;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h
new file mode 100644
index 0000000..2376fe3
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschema_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QXMLSCHEMA_P_H
+#define QXMLSCHEMA_P_H
+
+#include "qabstractmessagehandler.h"
+#include "qabstracturiresolver.h"
+#include "qautoptr_p.h"
+#include "qcoloringmessagehandler_p.h"
+#include "qreferencecountedvalue_p.h"
+
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemaparser_p.h"
+#include "qxsdschemaparsercontext_p.h"
+
+#include <QtCore/QSharedData>
+#include <QtNetwork/QNetworkAccessManager>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlSchemaPrivate : public QSharedData
+{
+ public:
+ QXmlSchemaPrivate(const QXmlNamePool &namePool);
+ QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext);
+ QXmlSchemaPrivate(const QXmlSchemaPrivate &other);
+
+ void load(const QUrl &source, const QString &targetNamespace);
+ void load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace);
+ void load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace);
+ bool isValid() const;
+ QXmlNamePool namePool() const;
+ QUrl documentUri() const;
+ void setMessageHandler(QAbstractMessageHandler *handler);
+ QAbstractMessageHandler *messageHandler() const;
+ void setUriResolver(const QAbstractUriResolver *resolver);
+ const QAbstractUriResolver *uriResolver() const;
+ void setNetworkAccessManager(QNetworkAccessManager *networkmanager);
+ QNetworkAccessManager *networkAccessManager() const;
+
+ QXmlNamePool m_namePool;
+ QAbstractMessageHandler* m_userMessageHandler;
+ const QAbstractUriResolver* m_uriResolver;
+ QNetworkAccessManager* m_userNetworkAccessManager;
+ QPatternist::ReferenceCountedValue<QAbstractMessageHandler>::Ptr m_messageHandler;
+ QPatternist::ReferenceCountedValue<QNetworkAccessManager>::Ptr m_networkAccessManager;
+
+ QPatternist::XsdSchemaContext::Ptr m_schemaContext;
+ QPatternist::XsdSchemaParserContext::Ptr m_schemaParserContext;
+ bool m_schemaIsValid;
+ QUrl m_documentUri;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp
new file mode 100644
index 0000000..682d34f
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxmlschemavalidator.h"
+#include "qxmlschemavalidator_p.h"
+
+#include "qacceltreeresourceloader_p.h"
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+#include "qxsdvalidatinginstancereader_p.h"
+
+#include <QtCore/QBuffer>
+#include <QtCore/QIODevice>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QXmlSchemaValidator
+
+ \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema.
+
+ \reentrant
+ \since 4.6
+ \ingroup xml-tools
+
+ The QXmlSchemaValidator class loads, parses an XML instance document and validates it
+ against a W3C XML Schema that has been compiled with \l{QXmlSchema}.
+
+ The following example shows how to load a XML Schema from a local
+ file, check whether it is a valid schema document and use it for validation
+ of an XML instance document:
+
+ \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 3
+
+ \section1 XML Schema Version
+
+ This class implements schema validation according to the \l{XML Schema} 1.0
+ specification.
+
+ \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example}
+*/
+
+/*!
+ Constructs a schema validator.
+ The schema used for validation must be referenced in the XML instance document
+ via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
+ */
+QXmlSchemaValidator::QXmlSchemaValidator()
+ : d(new QXmlSchemaValidatorPrivate(QXmlSchema()))
+{
+}
+
+/*!
+ Constructs a schema validator that will use \a schema for validation.
+ If an empty \l {QXmlSchema} schema is passed to the validator, the schema used
+ for validation must be referenced in the XML instance document
+ via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute.
+ */
+QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema)
+ : d(new QXmlSchemaValidatorPrivate(schema))
+{
+}
+
+/*!
+ Destroys this QXmlSchemaValidator.
+ */
+QXmlSchemaValidator::~QXmlSchemaValidator()
+{
+ delete d;
+}
+
+/*!
+ Sets the \a schema that shall be used for further validation.
+ If the schema is empty, the schema used for validation must be referenced
+ in the XML instance document via the \c xsi:schemaLocation or
+ \c xsi:noNamespaceSchemaLocation attribute.
+ */
+void QXmlSchemaValidator::setSchema(const QXmlSchema &schema)
+{
+ d->setSchema(schema);
+}
+
+/*!
+ Validates the XML instance document read from \a data with the
+ given \a documentUri against the schema.
+
+ Returns \c true if the XML instance document is valid according to the
+ schema, \c false otherwise.
+
+ Example:
+
+ \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 2
+ */
+bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const
+{
+ QByteArray localData(data);
+
+ QBuffer buffer(&localData);
+ buffer.open(QIODevice::ReadOnly);
+
+ return validate(&buffer, documentUri);
+}
+
+/*!
+ Validates the XML instance document read from \a source against the schema.
+
+ Returns \c true if the XML instance document is valid according to the
+ schema, \c false otherwise.
+
+ Example:
+
+ \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 0
+ */
+bool QXmlSchemaValidator::validate(const QUrl &source) const
+{
+ d->m_context->setMessageHandler(messageHandler());
+ d->m_context->setUriResolver(uriResolver());
+ d->m_context->setNetworkAccessManager(networkAccessManager());
+
+ const QPatternist::AutoPtr<QNetworkReply> reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(),
+ d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError));
+ if (reply)
+ return validate(reply.data(), source);
+ else
+ return false;
+}
+
+/*!
+ Validates the XML instance document read from \a source with the
+ given \a documentUri against the schema.
+
+ Returns \c true if the XML instance document is valid according to the
+ schema, \c false otherwise.
+
+ Example:
+
+ \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 1
+ */
+bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const
+{
+ if (!source) {
+ qWarning("A null QIODevice pointer cannot be passed.");
+ return false;
+ }
+
+ if (!source->isReadable()) {
+ qWarning("The device must be readable.");
+ return false;
+ }
+
+ const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri);
+
+ d->m_context->setMessageHandler(messageHandler());
+ d->m_context->setUriResolver(uriResolver());
+ d->m_context->setNetworkAccessManager(networkAccessManager());
+
+ QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(),
+ d->m_context->networkAccessManager()));
+
+ QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder<true>::SourceLocationsFeature);
+
+ QPatternist::Item item;
+ try {
+ item = loader.openDocument(source, normalizedUri, d->m_context);
+ } catch (QPatternist::Exception exception) {
+ return false;
+ }
+
+ QXmlNodeModelIndex index = item.asNode();
+ const QAbstractXmlNodeModel *model = item.asNode().model();
+
+ QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model);
+
+ QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context);
+ if (d->m_schema)
+ reader.addSchema(d->m_schema, d->m_schemaDocumentUri);
+ try {
+ reader.read();
+ } catch (QPatternist::Exception exception) {
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Returns the name pool used by this QXmlSchemaValidator for constructing \l
+ {QXmlName} {names}. There is no setter for the name pool, because
+ mixing name pools causes errors due to name confusion.
+ */
+QXmlNamePool QXmlSchemaValidator::namePool() const
+{
+ return d->m_namePool;
+}
+
+/*!
+ Returns the schema that is used for validation.
+ */
+QXmlSchema QXmlSchemaValidator::schema() const
+{
+ return d->m_originalSchema;
+}
+
+/*!
+ Changes the \l {QAbstractMessageHandler}{message handler} for this
+ QXmlSchemaValidator to \a handler. The schema validator sends all parsing and
+ validation messages to this message handler. QXmlSchemaValidator does not take
+ ownership of \a handler.
+
+ Normally, the default message handler is sufficient. It writes
+ compile and validation messages to \e stderr. The default message
+ handler includes color codes if \e stderr can render colors.
+
+ When QXmlSchemaValidator calls QAbstractMessageHandler::message(),
+ the arguments are as follows:
+
+ \table
+ \header
+ \o message() argument
+ \o Semantics
+ \row
+ \o QtMsgType type
+ \o Only QtWarningMsg and QtFatalMsg are used. The former
+ identifies a warning, while the latter identifies an error.
+ \row
+ \o const QString & description
+ \o An XHTML document which is the actual message. It is translated
+ into the current language.
+ \row
+ \o const QUrl &identifier
+ \o Identifies the error with a URI, where the fragment is
+ the error code, and the rest of the URI is the error namespace.
+ \row
+ \o const QSourceLocation & sourceLocation
+ \o Identifies where the error occurred.
+ \endtable
+
+ */
+void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ d->m_userMessageHandler = handler;
+}
+
+/*!
+ Returns the message handler that handles parsing and validation
+ messages for this QXmlSchemaValidator.
+ */
+QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const
+{
+ if (d->m_userMessageHandler)
+ return d->m_userMessageHandler;
+
+ return d->m_messageHandler.data()->value;
+}
+
+/*!
+ Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take
+ ownership of \a resolver.
+
+ \sa uriResolver()
+ */
+void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver)
+{
+ d->m_uriResolver = resolver;
+}
+
+/*!
+ Returns the schema's URI resolver. If no URI resolver has been set,
+ QtXmlPatterns will use the URIs in instance documents as they are.
+
+ The URI resolver provides a level of abstraction, or \e{polymorphic
+ URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
+ it can translate obsolete or invalid URIs to valid ones.
+
+ When QtXmlPatterns calls QAbstractUriResolver::resolve() the
+ absolute URI is the URI mandated by the schema specification, and the
+ relative URI is the URI specified by the user.
+
+ \sa setUriResolver()
+ */
+const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const
+{
+ return d->m_uriResolver;
+}
+
+/*!
+ Sets the network manager to \a manager.
+ QXmlSchemaValidator does not take ownership of \a manager.
+
+ \sa networkAccessManager()
+ */
+void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager)
+{
+ d->m_userNetworkAccessManager = manager;
+}
+
+/*!
+ Returns the network manager, or 0 if it has not been set.
+
+ \sa setNetworkAccessManager()
+ */
+QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const
+{
+ if (d->m_userNetworkAccessManager)
+ return d->m_userNetworkAccessManager;
+
+ return d->m_networkAccessManager.data()->value;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h
new file mode 100644
index 0000000..7121d19
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschemavalidator.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLSCHEMAVALIDATOR_H
+#define QXMLSCHEMAVALIDATOR_H
+
+#include <QtCore/QUrl>
+#include <QtXmlPatterns/QXmlNamePool>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QAbstractMessageHandler;
+class QAbstractUriResolver;
+class QIODevice;
+class QNetworkAccessManager;
+class QUrl;
+class QXmlNamePool;
+class QXmlSchema;
+class QXmlSchemaValidatorPrivate;
+
+class Q_XMLPATTERNS_EXPORT QXmlSchemaValidator
+{
+ public:
+ QXmlSchemaValidator();
+ QXmlSchemaValidator(const QXmlSchema &schema);
+ ~QXmlSchemaValidator();
+
+ void setSchema(const QXmlSchema &schema);
+
+ bool validate(const QUrl &source) const;
+ bool validate(QIODevice *source, const QUrl &documentUri = QUrl()) const;
+ bool validate(const QByteArray &data, const QUrl &documentUri = QUrl()) const;
+
+ QXmlNamePool namePool() const;
+ QXmlSchema schema() const;
+
+ void setMessageHandler(QAbstractMessageHandler *handler);
+ QAbstractMessageHandler *messageHandler() const;
+
+ void setUriResolver(const QAbstractUriResolver *resolver);
+ const QAbstractUriResolver *uriResolver() const;
+
+ void setNetworkAccessManager(QNetworkAccessManager *networkmanager);
+ QNetworkAccessManager *networkAccessManager() const;
+
+ private:
+ QXmlSchemaValidatorPrivate* const d;
+
+ Q_DISABLE_COPY(QXmlSchemaValidator)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h
new file mode 100644
index 0000000..fb9492a
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QXMLSCHEMAVALIDATOR_P_H
+#define QXMLSCHEMAVALIDATOR_P_H
+
+#include "qabstractmessagehandler.h"
+#include "qabstracturiresolver.h"
+#include "qautoptr_p.h"
+#include "qcoloringmessagehandler_p.h"
+#include "qxmlschema.h"
+#include "qxmlschema_p.h"
+
+#include "qxsdschemacontext_p.h"
+#include "qxsdschema_p.h"
+
+#include <QtNetwork/QNetworkAccessManager>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlSchemaValidatorPrivate
+{
+public:
+ QXmlSchemaValidatorPrivate(const QXmlSchema &schema)
+ : m_namePool(schema.namePool())
+ , m_userMessageHandler(0)
+ , m_uriResolver(0)
+ , m_userNetworkAccessManager(0)
+ {
+ setSchema(schema);
+
+ const QXmlSchemaPrivate *p = schema.d;
+
+ // initialize the environment properties with the ones from the schema
+
+ if (p->m_userNetworkAccessManager) // schema has user defined network access manager
+ m_userNetworkAccessManager = p->m_userNetworkAccessManager;
+ else
+ m_networkAccessManager = p->m_networkAccessManager;
+
+ if (p->m_userMessageHandler) // schema has user defined message handler
+ m_userMessageHandler = p->m_userMessageHandler;
+ else
+ m_messageHandler = p->m_messageHandler;
+
+ m_uriResolver = p->m_uriResolver;
+ }
+
+ void setSchema(const QXmlSchema &schema)
+ {
+ // use same name pool as the schema
+ m_namePool = schema.namePool();
+ m_schema = schema.d->m_schemaParserContext->schema();
+ m_schemaDocumentUri = schema.documentUri();
+
+ // create a new schema context
+ m_context = QPatternist::XsdSchemaContext::Ptr(new QPatternist::XsdSchemaContext(m_namePool.d));
+ m_context->m_schemaTypeFactory = schema.d->m_schemaContext->m_schemaTypeFactory;
+ m_context->m_builtinTypesFacetList = schema.d->m_schemaContext->m_builtinTypesFacetList;
+
+ m_originalSchema = schema;
+ }
+
+ QXmlNamePool m_namePool;
+ QAbstractMessageHandler* m_userMessageHandler;
+ const QAbstractUriResolver* m_uriResolver;
+ QNetworkAccessManager* m_userNetworkAccessManager;
+ QPatternist::ReferenceCountedValue<QAbstractMessageHandler>::Ptr m_messageHandler;
+ QPatternist::ReferenceCountedValue<QNetworkAccessManager>::Ptr m_networkAccessManager;
+
+ QXmlSchema m_originalSchema;
+ QPatternist::XsdSchemaContext::Ptr m_context;
+ QPatternist::XsdSchema::Ptr m_schema;
+ QUrl m_schemaDocumentUri;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlserializer.cpp b/src/xmlpatterns/api/qxmlserializer.cpp
new file mode 100644
index 0000000..5849e16
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlserializer.cpp
@@ -0,0 +1,653 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdynamiccontext_p.h"
+#include "qpatternistlocale_p.h"
+#include "qitem_p.h"
+#include "qxmlquery_p.h"
+#include "qxmlserializer_p.h"
+#include "qxmlserializer.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QXmlSerializerPrivate::QXmlSerializerPrivate(const QXmlQuery &query,
+ QIODevice *outputDevice)
+ : isPreviousAtomic(false),
+ state(QXmlSerializer::BeforeDocumentElement),
+ np(query.namePool().d),
+ device(outputDevice),
+ codec(QTextCodec::codecForMib(106)), /* UTF-8 */
+ query(query)
+{
+ hasClosedElement.reserve(EstimatedTreeDepth);
+ namespaces.reserve(EstimatedTreeDepth);
+ nameCache.reserve(EstimatedNameCount);
+
+ hasClosedElement.push(qMakePair(QXmlName(), true));
+
+ /*
+ We push the empty namespace such that first of all
+ namespaceBinding() won't assert on an empty QStack,
+ and such that the empty namespace is in-scope and
+ that the code doesn't attempt to declare it.
+
+ We push the XML namespace. Although we won't receive
+ declarations for it, we may output attributes by that
+ name.
+ */
+ QVector<QXmlName> defNss;
+ defNss.resize(2);
+ defNss[0] = QXmlName(StandardNamespaces::empty,
+ StandardLocalNames::empty,
+ StandardPrefixes::empty);
+ defNss[1] = QXmlName(StandardNamespaces::xml,
+ StandardLocalNames::empty,
+ StandardPrefixes::xml);
+
+ namespaces.push(defNss);
+
+ /* If we don't set this flag, QTextCodec will generate a BOM. */
+ converterState.flags = QTextCodec::IgnoreHeader;
+}
+
+/*!
+ \class QXmlSerializer
+ \brief The QXmlSerializer class is an implementation of QAbstractXmlReceiver for transforming XQuery output into unformatted XML.
+
+ \reentrant
+ \since 4.4
+ \ingroup xml-tools
+
+ QXmlSerializer translates an \l {XQuery Sequence} {XQuery sequence}, usually
+ the output of an QXmlQuery, into XML. Consider the example:
+
+ \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp 0
+
+ First it constructs a \l {QXmlQuery} {query} that gets the
+ first paragraph from document \c index.html. Then it constructs
+ an instance of this class with the \l {QXmlQuery} {query} and
+ \l {QIODevice} {myOutputDevice}. Finally, it
+ \l {QXmlQuery::evaluateTo()} {evaluates} the
+ \l {QXmlQuery} {query}, producing an ordered sequence of calls
+ to the serializer's callback functions. The sequence of callbacks
+ transforms the query output to XML and writes it to
+ \l {QIODevice} {myOutputDevice}.
+
+ QXmlSerializer will:
+
+ \list
+ \o Declare namespaces when needed,
+
+ \o Use appropriate escaping, when characters can't be
+ represented in the XML,
+
+ \o Handle line endings appropriately,
+
+ \o Report errors, when it can't serialize the content, e.g.,
+ when asked to serialize an attribute that is a top-level node,
+ or when more than one top-level element is encountered.
+
+ \endlist
+
+ If an error occurs during serialization, result is undefined
+ unless the serializer is driven through a call to
+ QXmlQuery::evaluateTo().
+
+ If the generated XML should be indented and formatted for reading,
+ use QXmlFormatter.
+
+ \sa {http://www.w3.org/TR/xslt-xquery-serialization/}{XSLT 2.0 and XQuery 1.0 Serialization}
+
+ \sa QXmlFormatter
+ */
+
+/*!
+ Constructs a serializer that uses the name pool and message
+ handler in \a query, and writes the output to \a outputDevice.
+
+ \a outputDevice must be a valid, non-null device that is open in
+ write mode, otherwise behavior is undefined.
+
+ \a outputDevice must not be opened with QIODevice::Text because it
+ will cause the output to be incorrect. This class will ensure line
+ endings are serialized as according with the XML specification.
+ QXmlSerializer does not take ownership of \a outputDevice.
+ */
+QXmlSerializer::QXmlSerializer(const QXmlQuery &query,
+ QIODevice *outputDevice) : QAbstractXmlReceiver(new QXmlSerializerPrivate(query, outputDevice))
+{
+ if(!outputDevice)
+ {
+ qWarning("outputDevice cannot be null.");
+ return;
+ }
+
+ if(!outputDevice->isWritable())
+ {
+ qWarning("outputDevice must be opened in write mode.");
+ return;
+ }
+}
+
+/*!
+ \internal
+ */
+QXmlSerializer::QXmlSerializer(QAbstractXmlReceiverPrivate *d) : QAbstractXmlReceiver(d)
+{
+}
+
+/*!
+ \internal
+ */
+bool QXmlSerializer::atDocumentRoot() const
+{
+ Q_D(const QXmlSerializer);
+ return d->state == BeforeDocumentElement ||
+ (d->state == InsideDocumentElement && d->hasClosedElement.size() == 1);
+}
+
+/*!
+ \internal
+ */
+void QXmlSerializer::startContent()
+{
+ Q_D(QXmlSerializer);
+ if (!d->hasClosedElement.top().second) {
+ d->write('>');
+ d->hasClosedElement.top().second = true;
+ }
+}
+
+/*!
+ \internal
+ */
+void QXmlSerializer::writeEscaped(const QString &toEscape)
+{
+ if(toEscape.isEmpty()) /* Early exit. */
+ return;
+
+ QString result;
+ result.reserve(int(toEscape.length() * 1.1));
+ const int length = toEscape.length();
+
+ for(int i = 0; i < length; ++i)
+ {
+ const QChar c(toEscape.at(i));
+
+ if(c == QLatin1Char('<'))
+ result += QLatin1String("&lt;");
+ else if(c == QLatin1Char('>'))
+ result += QLatin1String("&gt;");
+ else if(c == QLatin1Char('&'))
+ result += QLatin1String("&amp;");
+ else
+ result += toEscape.at(i);
+ }
+
+ write(result);
+}
+
+/*!
+ \internal
+ */
+void QXmlSerializer::writeEscapedAttribute(const QString &toEscape)
+{
+ if(toEscape.isEmpty()) /* Early exit. */
+ return;
+
+ QString result;
+ result.reserve(int(toEscape.length() * 1.1));
+ const int length = toEscape.length();
+
+ for(int i = 0; i < length; ++i)
+ {
+ const QChar c(toEscape.at(i));
+
+ if(c == QLatin1Char('<'))
+ result += QLatin1String("&lt;");
+ else if(c == QLatin1Char('>'))
+ result += QLatin1String("&gt;");
+ else if(c == QLatin1Char('&'))
+ result += QLatin1String("&amp;");
+ else if(c == QLatin1Char('"'))
+ result += QLatin1String("&quot;");
+ else
+ result += toEscape.at(i);
+ }
+
+ write(result);
+}
+
+/*!
+ \internal
+ */
+void QXmlSerializer::write(const QString &content)
+{
+ Q_D(QXmlSerializer);
+ d->device->write(d->codec->fromUnicode(content.constData(), content.length(), &d->converterState));
+}
+
+/*!
+ \internal
+ */
+void QXmlSerializer::write(const QXmlName &name)
+{
+ Q_D(QXmlSerializer);
+ const QByteArray &cell = d->nameCache[name.code()];
+
+ if(cell.isNull())
+ {
+ QByteArray &mutableCell = d->nameCache[name.code()];
+
+ const QString content(d->np->toLexical(name));
+ mutableCell = d->codec->fromUnicode(content.constData(),
+ content.length(),
+ &d->converterState);
+ d->device->write(mutableCell);
+ }
+ else
+ d->device->write(cell);
+}
+
+/*!
+ \internal
+ */
+void QXmlSerializer::write(const char *const chars)
+{
+ Q_D(QXmlSerializer);
+ d->device->write(chars);
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::startElement(const QXmlName &name)
+{
+ Q_D(QXmlSerializer);
+ Q_ASSERT(d->device);
+ Q_ASSERT(d->device->isWritable());
+ Q_ASSERT(d->codec);
+ Q_ASSERT(!name.isNull());
+
+ d->namespaces.push(QVector<QXmlName>());
+
+ if(atDocumentRoot())
+ {
+ if(d->state == BeforeDocumentElement)
+ d->state = InsideDocumentElement;
+ else if(d->state != InsideDocumentElement)
+ {
+ d->query.d->staticContext()->error(QtXmlPatterns::tr(
+ "Element %1 can't be serialized because it appears outside "
+ "the document element.").arg(formatKeyword(d->np, name)),
+ ReportContext::SENR0001,
+ d->query.d->expression().data());
+ }
+ }
+
+ startContent();
+ d->write('<');
+ write(name);
+
+ /* Ensure that the namespace URI used in the name gets outputted. */
+ namespaceBinding(name);
+
+ d->hasClosedElement.push(qMakePair(name, false));
+ d->isPreviousAtomic = false;
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::endElement()
+{
+ Q_D(QXmlSerializer);
+ const QPair<QXmlName, bool> e(d->hasClosedElement.pop());
+ d->namespaces.pop();
+
+ if(e.second)
+ {
+ write("</");
+ write(e.first);
+ d->write('>');
+ }
+ else
+ write("/>");
+
+ d->isPreviousAtomic = false;
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::attribute(const QXmlName &name,
+ const QStringRef &value)
+{
+ Q_D(QXmlSerializer);
+ Q_ASSERT(!name.isNull());
+
+ /* Ensure that the namespace URI used in the name gets outputted. */
+ {
+ /* Since attributes doesn't pick up the default namespace, a
+ * namespace declaration would cause trouble if we output it. */
+ if(name.prefix() != StandardPrefixes::empty)
+ namespaceBinding(name);
+ }
+
+ if(atDocumentRoot())
+ {
+ Q_UNUSED(d);
+ d->query.d->staticContext()->error(QtXmlPatterns::tr(
+ "Attribute %1 can't be serialized because it appears at "
+ "the top level.").arg(formatKeyword(d->np, name)),
+ ReportContext::SENR0001,
+ d->query.d->expression().data());
+ }
+ else
+ {
+ d->write(' ');
+ write(name);
+ write("=\"");
+ writeEscapedAttribute(value.toString());
+ d->write('"');
+ }
+}
+
+/*!
+ \internal
+ */
+bool QXmlSerializer::isBindingInScope(const QXmlName nb) const
+{
+ Q_D(const QXmlSerializer);
+ const int levelLen = d->namespaces.size();
+
+ if(nb.prefix() == StandardPrefixes::empty)
+ {
+ for(int lvl = levelLen - 1; lvl >= 0; --lvl)
+ {
+ const QVector<QXmlName> &scope = d->namespaces.at(lvl);
+ const int vectorLen = scope.size();
+
+ for(int s = vectorLen - 1; s >= 0; --s)
+ {
+ const QXmlName &nsb = scope.at(s);
+
+ if(nsb.prefix() == StandardPrefixes::empty)
+ return nsb.namespaceURI() == nb.namespaceURI();
+ }
+ }
+ }
+ else
+ {
+ for(int lvl = 0; lvl < levelLen; ++lvl)
+ {
+ const QVector<QXmlName> &scope = d->namespaces.at(lvl);
+ const int vectorLen = scope.size();
+
+ for(int s = 0; s < vectorLen; ++s)
+ {
+ const QXmlName &n = scope.at(s);
+ if (n.prefix() == nb.prefix() &&
+ n.namespaceURI() == nb.namespaceURI())
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::namespaceBinding(const QXmlName &nb)
+{
+ /*
+ * Writes out \a nb.
+ *
+ * Namespace bindings aren't looked up in a cache, because
+ * we typically receive very few.
+ */
+
+ Q_D(QXmlSerializer);
+ Q_ASSERT_X(!nb.isNull(), Q_FUNC_INFO,
+ "It makes no sense to pass a null QXmlName.");
+
+ Q_ASSERT_X((nb.namespaceURI() != StandardNamespaces::empty) ||
+ (nb.prefix() == StandardPrefixes::empty),
+ Q_FUNC_INFO,
+ "Undeclarations of prefixes aren't allowed in XML 1.0 "
+ "and aren't supposed to be received.");
+
+ if(nb.namespaceURI() == QPatternist::StandardNamespaces::StopNamespaceInheritance)
+ return;
+
+ if(isBindingInScope(nb))
+ return;
+
+ d->namespaces.top().append(nb);
+
+ if(nb.prefix() == StandardPrefixes::empty)
+ write(" xmlns");
+ else
+ {
+ write(" xmlns:");
+ write(d->np->stringForPrefix(nb.prefix()));
+ }
+
+ write("=\"");
+ writeEscapedAttribute(d->np->stringForNamespace(nb.namespaceURI()));
+ d->write('"');
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::comment(const QString &value)
+{
+ Q_D(QXmlSerializer);
+ Q_ASSERT_X(!value.contains(QLatin1String("--")),
+ Q_FUNC_INFO,
+ "Invalid input; it's the caller's responsibility to ensure "
+ "the input is correct.");
+
+ startContent();
+ write("<!--");
+ write(value);
+ write("-->");
+ d->isPreviousAtomic = false;
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::characters(const QStringRef &value)
+{
+ Q_D(QXmlSerializer);
+ d->isPreviousAtomic = false;
+ startContent();
+ writeEscaped(value.toString());
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::processingInstruction(const QXmlName &name,
+ const QString &value)
+{
+ Q_D(QXmlSerializer);
+ Q_ASSERT_X(!value.contains(QLatin1String("?>")),
+ Q_FUNC_INFO,
+ "Invalid input; it's the caller's responsibility to ensure "
+ "the input is correct.");
+
+ startContent();
+ write("<?");
+ write(name);
+ d->write(' ');
+ write(value);
+ write("?>");
+
+ d->isPreviousAtomic = false;
+}
+
+/*!
+ \internal
+ */
+void QXmlSerializer::item(const QPatternist::Item &outputItem)
+{
+ Q_D(QXmlSerializer);
+
+ if(outputItem.isAtomicValue())
+ {
+ if(d->isPreviousAtomic)
+ {
+ startContent();
+ d->write(' ');
+ writeEscaped(outputItem.stringValue());
+ }
+ else
+ {
+ d->isPreviousAtomic = true;
+ const QString value(outputItem.stringValue());
+
+ if(!value.isEmpty())
+ {
+ startContent();
+ writeEscaped(value);
+ }
+ }
+ }
+ else
+ {
+ startContent();
+ Q_ASSERT(outputItem.isNode());
+ sendAsNode(outputItem);
+ }
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::atomicValue(const QVariant &value)
+{
+ Q_UNUSED(value);
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::startDocument()
+{
+ Q_D(QXmlSerializer);
+ d->isPreviousAtomic = false;
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::endDocument()
+{
+ Q_D(QXmlSerializer);
+ d->isPreviousAtomic = false;
+}
+
+/*!
+
+ Returns a pointer to the output device. There is no corresponding
+ function to \e set the output device, because the output device must
+ be passed to the constructor. The serializer does not take ownership
+ of its IO device.
+ */
+QIODevice *QXmlSerializer::outputDevice() const
+{
+ Q_D(const QXmlSerializer);
+ return d->device;
+}
+
+/*!
+ Sets the codec the serializer will use for encoding its XML output.
+ The output codec is set to \a outputCodec. By default, the output
+ codec is set to the one for \c UTF-8. The serializer does not take
+ ownership of the codec.
+
+ \sa codec()
+
+ */
+void QXmlSerializer::setCodec(const QTextCodec *outputCodec)
+{
+ Q_D(QXmlSerializer);
+ d->codec = outputCodec;
+}
+
+/*!
+ Returns the codec being used by the serializer for encoding its
+ XML output.
+
+ \sa setCodec()
+ */
+const QTextCodec *QXmlSerializer::codec() const
+{
+ Q_D(const QXmlSerializer);
+ return d->codec;
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::startOfSequence()
+{
+}
+
+/*!
+ \reimp
+ */
+void QXmlSerializer::endOfSequence()
+{
+ /* If this function is changed to flush or close or something like that,
+ * take into consideration QXmlFormatter, especially
+ * QXmlFormatter::endOfSequence().
+ */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qxmlserializer.h b/src/xmlpatterns/api/qxmlserializer.h
new file mode 100644
index 0000000..ae0a69e
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlserializer.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLSERIALIZER_H
+#define QXMLSERIALIZER_H
+
+#include <QtXmlPatterns/QAbstractXmlReceiver>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(XmlPatterns)
+
+class QIODevice;
+class QTextCodec;
+class QXmlQuery;
+class QXmlSerializerPrivate;
+
+class Q_XMLPATTERNS_EXPORT QXmlSerializer : public QAbstractXmlReceiver
+{
+public:
+ QXmlSerializer(const QXmlQuery &query,
+ QIODevice *outputDevice);
+
+ virtual void namespaceBinding(const QXmlName &nb);
+
+ virtual void characters(const QStringRef &value);
+ virtual void comment(const QString &value);
+
+ virtual void startElement(const QXmlName &name);
+
+ virtual void endElement();
+
+ virtual void attribute(const QXmlName &name,
+ const QStringRef &value);
+
+ virtual void processingInstruction(const QXmlName &name,
+ const QString &value);
+
+ virtual void atomicValue(const QVariant &value);
+
+ virtual void startDocument();
+ virtual void endDocument();
+ virtual void startOfSequence();
+ virtual void endOfSequence();
+
+ QIODevice *outputDevice() const;
+
+ void setCodec(const QTextCodec *codec);
+ const QTextCodec *codec() const;
+
+ /* The members below are internal, not part of the public API, and
+ * unsupported. Using them leads to undefined behavior. */
+ virtual void item(const QPatternist::Item &item);
+protected:
+ QXmlSerializer(QAbstractXmlReceiverPrivate *d);
+
+private:
+ inline bool isBindingInScope(const QXmlName nb) const;
+
+ /**
+ * Where in the document the QXmlSerializer is currently working.
+ */
+ enum State
+ {
+ /**
+ * Before the document element. This is the XML prolog where the
+ * XML declaration, and possibly comments and processing
+ * instructions are found.
+ */
+ BeforeDocumentElement,
+
+ /**
+ * This is inside the document element, at any level.
+ */
+ InsideDocumentElement
+ };
+
+ /**
+ * If the current state is neither BeforeDocumentElement or
+ * AfterDocumentElement.
+ */
+ inline bool atDocumentRoot() const;
+
+ /**
+ * Closes any open element start tag. Must be called before outputting
+ * any element content.
+ */
+ inline void startContent();
+
+ /**
+ * Escapes content intended as text nodes for elements.
+ */
+ void writeEscaped(const QString &toEscape);
+
+ /**
+ * Identical to writeEscaped(), but also escapes quotes.
+ */
+ inline void writeEscapedAttribute(const QString &toEscape);
+
+ /**
+ * Writes out @p name.
+ */
+ inline void write(const QXmlName &name);
+
+ inline void write(const char *const chars);
+ /**
+ * Encodes and writes out @p content.
+ */
+ inline void write(const QString &content);
+
+ Q_DECLARE_PRIVATE(QXmlSerializer)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlserializer_p.h b/src/xmlpatterns/api/qxmlserializer_p.h
new file mode 100644
index 0000000..8aa525d
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlserializer_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QXMLSERIALIZER_P_H
+#define QXMLSERIALIZER_P_H
+
+#include <QtCore/QIODevice>
+#include <QtCore/QStack>
+#include <QtCore/QTextCodec>
+#include <QtXmlPatterns/QXmlQuery>
+#include <QtXmlPatterns/QXmlNamePool>
+#include <QtXmlPatterns/QXmlSerializer>
+
+#include "qnamepool_p.h"
+#include "qabstractxmlreceiver_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlSerializerPrivate : public QAbstractXmlReceiverPrivate
+{
+public:
+ QXmlSerializerPrivate(const QXmlQuery &q,
+ QIODevice *outputDevice);
+
+ QStack<QPair<QXmlName, bool> > hasClosedElement;
+ bool isPreviousAtomic;
+ QXmlSerializer::State state;
+ const QPatternist::NamePool::Ptr np;
+
+ /**
+ * This member worries me a bit. We never use it but nevertheless
+ * it is pushed and pops linear to startElement() and endElement().
+ * An optimization would be to at least merge it with hasClosedElement,
+ * but even better to push it on demand. That is, namespaceBinding()
+ * pushes it up to the tree depth first when it is needed.
+ */
+ QStack<QVector<QXmlName> > namespaces;
+
+ QIODevice * device;
+ const QTextCodec * codec;
+ QTextCodec::ConverterState converterState;
+ /**
+ * Name cache. Since encoding QStrings are rather expensive
+ * operations to do, and we on top of that would have to do
+ * it each time a name appears, we here map names to their
+ * encoded equivalents.
+ *
+ * This means that when writing out large documents, the serialization
+ * of names after a while is reduced to a hash lookup and passing an
+ * existing byte array.
+ *
+ * We use QXmlName::Code as key as opposed to merely QName, because the
+ * prefix is of significance.
+ */
+ QHash<QXmlName::Code, QByteArray> nameCache;
+ const QXmlQuery query;
+
+ inline void write(const char c);
+
+private:
+ enum Constants
+ {
+ EstimatedTreeDepth = 10,
+
+ /**
+ * We use a high count to avoid rehashing. We can afford it since we
+ * only allocate one hash for this.
+ */
+ EstimatedNameCount = 60
+ };
+};
+
+void QXmlSerializerPrivate::write(const char c)
+{
+ device->putChar(c);
+}
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/common.pri b/src/xmlpatterns/common.pri
new file mode 100644
index 0000000..27253d8
--- /dev/null
+++ b/src/xmlpatterns/common.pri
@@ -0,0 +1,18 @@
+# This qmake file is included by all Patternist projects and contains common Qt defines,
+# compiler warnings, and include paths.
+
+INCLUDEPATH += $$PWD/acceltree \
+ $$PWD/data \
+ $$PWD/api \
+ $$PWD/environment \
+ $$PWD/expr \
+ $$PWD/functions \
+ $$PWD/iterators \
+ $$PWD/janitors \
+ $$PWD/parser \
+ $$PWD/schema \
+ $$PWD/type \
+ $$PWD/utils
+
+DEPENDPATH += $$INCLUDEPATH
+
diff --git a/src/xmlpatterns/data/data.pri b/src/xmlpatterns/data/data.pri
new file mode 100644
index 0000000..ccfed42
--- /dev/null
+++ b/src/xmlpatterns/data/data.pri
@@ -0,0 +1,82 @@
+HEADERS += $$PWD/qabstractdatetime_p.h \
+ $$PWD/qabstractduration_p.h \
+ $$PWD/qabstractfloatcasters_p.h \
+ $$PWD/qabstractfloatmathematician_p.h \
+ $$PWD/qabstractfloat_p.h \
+ $$PWD/qanyuri_p.h \
+ $$PWD/qatomiccaster_p.h \
+ $$PWD/qatomiccasters_p.h \
+ $$PWD/qatomiccomparator_p.h \
+ $$PWD/qatomiccomparators_p.h \
+ $$PWD/qatomicmathematician_p.h \
+ $$PWD/qatomicmathematicians_p.h \
+ $$PWD/qatomicstring_p.h \
+ $$PWD/qbase64binary_p.h \
+ $$PWD/qboolean_p.h \
+ $$PWD/qcommonvalues_p.h \
+ $$PWD/qcomparisonfactory_p.h \
+ $$PWD/qdate_p.h \
+ $$PWD/qdaytimeduration_p.h \
+ $$PWD/qdecimal_p.h \
+ $$PWD/qderivedinteger_p.h \
+ $$PWD/qderivedstring_p.h \
+ $$PWD/qduration_p.h \
+ $$PWD/qgday_p.h \
+ $$PWD/qgmonthday_p.h \
+ $$PWD/qgmonth_p.h \
+ $$PWD/qgyearmonth_p.h \
+ $$PWD/qgyear_p.h \
+ $$PWD/qhexbinary_p.h \
+ $$PWD/qinteger_p.h \
+ $$PWD/qitem_p.h \
+ $$PWD/qnodebuilder_p.h \
+ $$PWD/qqnamevalue_p.h \
+ $$PWD/qresourceloader_p.h \
+ $$PWD/qschemadatetime_p.h \
+ $$PWD/qschemanumeric_p.h \
+ $$PWD/qschematime_p.h \
+ $$PWD/qsorttuple.cpp \
+ $$PWD/quntypedatomic_p.h \
+ $$PWD/qvalidationerror_p.h \
+ $$PWD/qvaluefactory_p.h \
+ $$PWD/qyearmonthduration_p.h
+
+SOURCES += $$PWD/qabstractdatetime.cpp \
+ $$PWD/qabstractduration.cpp \
+ $$PWD/qanyuri.cpp \
+ $$PWD/qatomiccaster.cpp \
+ $$PWD/qatomiccasters.cpp \
+ $$PWD/qatomiccomparator.cpp \
+ $$PWD/qatomiccomparators.cpp \
+ $$PWD/qatomicmathematician.cpp \
+ $$PWD/qatomicmathematicians.cpp \
+ $$PWD/qatomicstring.cpp \
+ $$PWD/qatomicvalue.cpp \
+ $$PWD/qbase64binary.cpp \
+ $$PWD/qboolean.cpp \
+ $$PWD/qcommonvalues.cpp \
+ $$PWD/qcomparisonfactory.cpp \
+ $$PWD/qdate.cpp \
+ $$PWD/qdaytimeduration.cpp \
+ $$PWD/qdecimal.cpp \
+ $$PWD/qduration.cpp \
+ $$PWD/qgday.cpp \
+ $$PWD/qgmonth.cpp \
+ $$PWD/qgmonthday.cpp \
+ $$PWD/qgyear.cpp \
+ $$PWD/qgyearmonth.cpp \
+ $$PWD/qhexbinary.cpp \
+ $$PWD/qinteger.cpp \
+ $$PWD/qitem.cpp \
+ $$PWD/qnodebuilder.cpp \
+ $$PWD/qnodemodel.cpp \
+ $$PWD/qqnamevalue.cpp \
+ $$PWD/qresourceloader.cpp \
+ $$PWD/qschemadatetime.cpp \
+ $$PWD/qschemanumeric.cpp \
+ $$PWD/qschematime.cpp \
+ $$PWD/qsorttuple.cpp \
+ $$PWD/quntypedatomic.cpp \
+ $$PWD/qvalidationerror.cpp \
+ $$PWD/qvaluefactory.cpp \
+ $$PWD/qyearmonthduration.cpp
diff --git a/src/xmlpatterns/data/qabstractdatetime.cpp b/src/xmlpatterns/data/qabstractdatetime.cpp
new file mode 100644
index 0000000..900a516
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractdatetime.cpp
@@ -0,0 +1,400 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AbstractDateTime::AbstractDateTime(const QDateTime &dateTime) : m_dateTime(dateTime)
+{
+ Q_ASSERT(dateTime.isValid());
+}
+
+#define badData(msg) errorMessage = ValidationError::createError(msg); return QDateTime()
+#define getCapt(sym) ((captTable.sym == -1) ? QString() : capts.at(captTable.sym))
+#define getSafeCapt(sym) ((captTable.sym == -1) ? QString() : capts.value(captTable.sym))
+
+QDateTime AbstractDateTime::create(AtomicValue::Ptr &errorMessage,
+ const QString &lexicalSource,
+ const CaptureTable &captTable)
+{
+ QRegExp myExp(captTable.regExp);
+
+ if(!myExp.exactMatch(lexicalSource))
+ {
+ badData(QString());
+ }
+
+ const QStringList capts(myExp.capturedTexts());
+ const QString yearStr(getCapt(year));
+
+ if(yearStr.size() > 4 && yearStr.at(0) == QLatin1Char('0'))
+ {
+ badData(QtXmlPatterns::tr("Year %1 is invalid because it begins with %2.")
+ .arg(formatData(yearStr)).arg(formatData("0")));
+ }
+
+ /* If the strings are empty, load default values which are
+ * guranteed to pass the validness tests. */
+ const QString monthStr(getCapt(month));
+ const QString dayStr(getCapt(day));
+ YearProperty year = yearStr.isEmpty() ? DefaultYear : yearStr.toInt();
+ if(getCapt(yearSign) == QChar::fromLatin1('-'))
+ year = -year;
+ const MonthProperty month = monthStr.isEmpty() ? DefaultMonth : monthStr.toInt();
+ const MonthProperty day = dayStr.isEmpty() ? DefaultDay : dayStr.toInt();
+
+ if(!QDate::isValid(year, month, day))
+ {
+ /* Try to give an intelligent message. */
+ if(day > 31 || day < 1)
+ {
+ badData(QtXmlPatterns::tr("Day %1 is outside the range %2..%3.")
+ .arg(formatData(QString::number(day)))
+ .arg(formatData("01"))
+ .arg(formatData("31")));
+ }
+ else if(month > 12 || month < -12 || month == 0)
+ {
+ badData(QtXmlPatterns::tr("Month %1 is outside the range %2..%3.")
+ .arg(month)
+ .arg(formatData("01"))
+ .arg(formatData("12")));
+
+ }
+ else if(QDate::isValid(DefaultYear, month, day))
+ {
+ /* We can't use the badData() macro here because we need a different
+ * error code: FODT0001 instead of FORG0001. */
+ errorMessage = ValidationError::createError(QtXmlPatterns::tr(
+ "Overflow: Can't represent date %1.")
+ .arg(formatData(QLatin1String("%1-%2-%3"))
+ .arg(year).arg(month).arg(day)),
+ ReportContext::FODT0001);
+ return QDateTime();
+ }
+ else
+ {
+ badData(QtXmlPatterns::tr("Day %1 is invalid for month %2.")
+ .arg(formatData(QString::number(day)))
+ .arg(formatData(QString::number(month))));
+ }
+ }
+
+ /* Parse the zone offset. */
+ ZoneOffsetParseResult zoResult;
+ const ZOTotal offset = parseZoneOffset(zoResult, capts, captTable);
+
+ if(zoResult == Error)
+ {
+ errorMessage = ValidationError::createError();
+ /* We encountered an error, so stop processing. */
+ return QDateTime();
+ }
+
+ QDate date(year, month, day);
+
+ /* Only deal with time if time is needed. */
+ if(captTable.hour == -1)
+ {
+ QDateTime result(date);
+ setUtcOffset(result, zoResult, offset);
+ return result;
+ }
+ else
+ {
+ /* Now, it's time for the time-part.
+ *
+ * If the strings are empty, toInt() will return 0, which
+ * in all cases is valid properties. */
+ const QString hourStr(getCapt(hour));
+ const QString minutesStr(getCapt(minutes));
+ const QString secondsStr(getCapt(seconds));
+ HourProperty hour = hourStr.toInt();
+ const MinuteProperty mins = minutesStr.toInt();
+ const SecondProperty secs = secondsStr.toInt();
+
+ QString msecondsStr(getSafeCapt(mseconds));
+ if(!msecondsStr.isEmpty())
+ msecondsStr = msecondsStr.leftJustified(3, QLatin1Char('0'), true);
+ const MSecondProperty msecs = msecondsStr.toInt();
+
+ if(hour == 24)
+ {
+ /* 24:00:00.00 is an invalid time for QTime, so handle it here. */
+ if(mins != 0 || secs != 0 || msecs != 0)
+ {
+ badData(QtXmlPatterns::tr("Time 24:%1:%2.%3 is invalid. "
+ "Hour is 24, but minutes, seconds, "
+ "and milliseconds are not all 0; ")
+ .arg(mins).arg(secs).arg(msecs));
+ }
+ else
+ {
+ hour = 0;
+ date = date.addDays(1);
+ }
+ }
+ else if(!QTime::isValid(hour, mins, secs, msecs))
+ {
+ badData(QtXmlPatterns::tr("Time %1:%2:%3.%4 is invalid.")
+ .arg(hour).arg(mins).arg(secs).arg(msecs));
+ }
+
+ const QTime time(hour, mins, secs, msecs);
+ Q_ASSERT(time.isValid());
+
+ QDateTime result(date, time);
+ setUtcOffset(result, zoResult, offset);
+ return result;
+ }
+}
+
+ZOTotal AbstractDateTime::parseZoneOffset(ZoneOffsetParseResult &result,
+ const QStringList &capts,
+ const CaptureTable &captTable)
+{
+ const QString zoneOffsetSignStr(getCapt(zoneOffsetSign));
+
+ if(zoneOffsetSignStr.isEmpty())
+ {
+ const QString zoneOffsetUTCStr(getCapt(zoneOffsetUTCSymbol));
+ Q_ASSERT(zoneOffsetUTCStr.isEmpty() || zoneOffsetUTCStr == QLatin1String("Z"));
+
+ if(zoneOffsetUTCStr.isEmpty())
+ result = LocalTime;
+ else
+ result = UTC;
+
+ return 0;
+ }
+
+ Q_ASSERT(zoneOffsetSignStr == QLatin1String("-") || zoneOffsetSignStr == QLatin1String("+"));
+
+ const QString zoneOffsetHourStr(getCapt(zoneOffsetHour));
+ Q_ASSERT(!zoneOffsetHourStr.isEmpty());
+ const ZOHourProperty zoHour = zoneOffsetHourStr.toInt();
+
+ if(zoHour > 14 || zoHour < -14)
+ {
+ result = Error;
+ return 0;
+ /*
+ badZOData(QtXmlPatterns::tr("%1 it is not a valid hour property in a zone offset. "
+ "It must be less than or equal to 14.").arg(zoHour));
+ */
+ }
+
+ const QString zoneOffsetMinuteStr(getCapt(zoneOffsetMinute));
+ Q_ASSERT(!zoneOffsetMinuteStr.isEmpty());
+ const ZOHourProperty zoMins = zoneOffsetMinuteStr.toInt();
+
+ if(zoHour == 14 && zoMins != 0)
+ {
+ /*
+ badZOData(QtXmlPatterns::tr("When the hour property in a zone offset is 14, the minute property "
+ "must be 0, not %1.").arg(zoMins));
+ */
+ result = Error;
+ return 0;
+ }
+ else if(zoMins > 59 || zoMins < -59)
+ {
+ /*
+ badZOData(QtXmlPatterns::tr("The minute property in a zone offset cannot be larger than 59. "
+ "%1 is therefore invalid.").arg(zoMins));
+ */
+ result = Error;
+ return 0;
+ }
+
+ if(zoHour == 0 && zoMins == 0) /* "-00:00" and "+00:00" is equal to 'Z'. */
+ {
+ result = UTC;
+ return 0;
+ }
+ else
+ {
+ ZOTotal zoneOffset = (zoHour * 60 + zoMins) * 60;
+
+ if(zoneOffsetSignStr == QChar::fromLatin1('-'))
+ zoneOffset = -zoneOffset;
+
+ result = Offset;
+ return zoneOffset;
+ }
+}
+//#undef badZOData
+
+void AbstractDateTime::setUtcOffset(QDateTime &result,
+ const ZoneOffsetParseResult zoResult,
+ const int zoOffset)
+{
+ if(zoResult == UTC)
+ result.setTimeSpec(Qt::UTC);
+ else if(zoResult == LocalTime)
+ result.setTimeSpec(Qt::LocalTime);
+ else
+ {
+ Q_ASSERT(zoResult == Offset);
+ result.setUtcOffset(zoOffset);
+ }
+}
+
+#undef badData
+#undef getCapt
+#undef getSafeCapt
+
+bool AbstractDateTime::isRangeValid(const QDate &date,
+ QString &message)
+{
+ if(date.isValid())
+ return true;
+ else
+ {
+ message = QtXmlPatterns::tr("Overflow: Date can't be represented.");
+ return false;
+ }
+}
+
+QString AbstractDateTime::dateToString() const
+{
+ return m_dateTime.toString(QLatin1String("yyyy-MM-dd"));
+}
+
+QString AbstractDateTime::serializeMSeconds(const MSecondProperty mseconds)
+{
+ QString retval;
+ retval.append(QLatin1Char('.'));
+ int div = 100;
+ MSecondProperty msecs = mseconds;
+
+ while(msecs > 0)
+ {
+ int d = msecs / div;
+ retval.append(QLatin1Char(d + '0'));
+ msecs = msecs % div;
+ div = div / 10;
+ }
+
+ return retval;
+}
+
+QString AbstractDateTime::timeToString() const
+{
+ QString base(m_dateTime.toString(QLatin1String("hh:mm:ss")));
+ const MSecondProperty msecs = m_dateTime.time().msec();
+
+ if(msecs)
+ base.append(serializeMSeconds(msecs));
+
+ return base;
+}
+
+QString AbstractDateTime::zoneOffsetToString() const
+{
+ switch(m_dateTime.timeSpec())
+ {
+ case Qt::LocalTime:
+ return QString();
+ case Qt::UTC:
+ return QLatin1String("Z");
+ default:
+ {
+ Q_ASSERT(m_dateTime.timeSpec() == Qt::OffsetFromUTC);
+
+ const int zoneOffset = m_dateTime.utcOffset();
+ Q_ASSERT(zoneOffset != 0);
+ const int posZoneOffset = qAbs(zoneOffset);
+
+ /* zoneOffset is in seconds. */
+ const int hours = posZoneOffset/(60 * 60);
+ const int minutes = (posZoneOffset % (60 * 60)) / 60;
+
+ QString result;
+ result.reserve(6);
+
+ result.append(zoneOffset < 0 ? QLatin1Char('-') : QLatin1Char('+'));
+ result.append(QString::number(hours).rightJustified(2, QLatin1Char('0')));
+ result.append(QLatin1Char(':'));
+ result.append(QString::number(minutes).rightJustified(2, QLatin1Char('0')));
+ return result;
+ }
+ }
+}
+
+void AbstractDateTime::copyTimeSpec(const QDateTime &from,
+ QDateTime &to)
+{
+ switch(from.timeSpec())
+ {
+ case Qt::UTC:
+ /* Fallthrough. */
+ case Qt::LocalTime:
+ {
+ to.setTimeSpec(from.timeSpec());
+ return;
+ }
+ case Qt::OffsetFromUTC:
+ {
+ to.setUtcOffset(from.utcOffset());
+ Q_ASSERT(to.timeSpec() == Qt::OffsetFromUTC);
+ return;
+ }
+ }
+}
+
+Item AbstractDateTime::fromValue(const QDateTime &) const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Calling AbstractDateTime::fromDateTime() makes no sense.");
+ return Item();
+}
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qabstractdatetime_p.h b/src/xmlpatterns/data/qabstractdatetime_p.h
new file mode 100644
index 0000000..3ad169b
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractdatetime_p.h
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AbstractDateTime_H
+#define Patternist_AbstractDateTime_H
+
+#include <QDateTime>
+#include <QRegExp>
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for classes implementing values related to time, date or both.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">XML Schema
+ * Part 2: Datatypes Second Edition, 3.2.7 dateTime</a>
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/#dates-and-times">XQuery
+ * 1.0 and XPath 2.0 Data Model (XDM), 3.3.2 Dates and Times</a>
+ * @see <a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">A summary of
+ * the international standard date and time notation, Markus Kuhn</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Iso_date">ISO 8601,
+ * From Wikipedia, the free encyclopedia</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class AbstractDateTime : public AtomicValue
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AbstractDateTime> Ptr;
+
+ AbstractDateTime(const QDateTime &dateTime);
+
+ enum
+ {
+ DefaultYear = 2000,
+ DefaultMonth = 1,
+ DefaultDay = 1
+ };
+
+ /**
+ * @returns the date time this class represents, as a QDateTime.
+ */
+ inline const QDateTime &toDateTime() const
+ {
+ return m_dateTime;
+ }
+
+
+ /**
+ * @short Acts as a mapping table for AbstractDateTime::create()
+ * and describes where certain fields in a QRegExp pattern can be found
+ * for a particular W3C XML Schema date/time type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class CaptureTable
+ {
+ public:
+ CaptureTable(const QRegExp &exp,
+ const qint8 zoneOffsetSignP,
+ const qint8 zoneOffsetHourP,
+ const qint8 zoneOffsetMinuteP,
+ const qint8 zoneOffsetUTCSymbolP,
+ const qint8 yearP,
+ const qint8 monthP = -1,
+ const qint8 dayP = -1,
+ const qint8 hourP = -1,
+ const qint8 minutesP = -1,
+ const qint8 secondsP = -1,
+ const qint8 msecondsP = -1,
+ const qint8 yearSignP = -1) : regExp(exp)
+ , zoneOffsetSign(zoneOffsetSignP)
+ , zoneOffsetHour(zoneOffsetHourP)
+ , zoneOffsetMinute(zoneOffsetMinuteP)
+ , zoneOffsetUTCSymbol(zoneOffsetUTCSymbolP)
+ , year(yearP)
+ , month(monthP)
+ , day(dayP)
+ , hour(hourP)
+ , minutes(minutesP)
+ , seconds(secondsP)
+ , mseconds(msecondsP)
+ , yearSign(yearSignP)
+ {
+ Q_ASSERT(exp.isValid());
+ }
+
+ const QRegExp regExp;
+ const qint8 zoneOffsetSign;
+ const qint8 zoneOffsetHour;
+ const qint8 zoneOffsetMinute;
+ const qint8 zoneOffsetUTCSymbol;
+ const qint8 year;
+ const qint8 month;
+ const qint8 day;
+ const qint8 hour;
+ const qint8 minutes;
+ const qint8 seconds;
+ const qint8 mseconds;
+ const qint8 yearSign;
+
+ private:
+ Q_DISABLE_COPY(CaptureTable)
+ };
+
+ /**
+ * @returns m_dateTime's time part converted to string. This is for
+ * example "12" or "01.023".
+ */
+ QString timeToString() const;
+
+ /**
+ * @returns m_dateTime's date part converted to string. This is for
+ * example "2004-05-12" or "-2004-05-12".
+ */
+ QString dateToString() const;
+
+ /**
+ * Serializes the milli seconds @p msecs into a string representation. For
+ * example, if @p msecs is 1, ".001" is returned; if @p msecs is 100 then
+ * is ".1" returned.
+ */
+ static QString serializeMSeconds(const MSecondProperty msecs);
+
+ /**
+ * A factory function for creating instances that are of the dynamic
+ * type of this class, that represents @p dt.
+ *
+ * The default implementation performs an assert() call. This function
+ * is not pure virtual because all sub-classes do not use it.
+ */
+ virtual Item fromValue(const QDateTime &dt) const;
+
+ /**
+ * Determines whether @p dt is a date-time that can be represented,
+ * and isn't too early or too late. If it is valid, @c true is returned. Otherwise,
+ * @c false is returned and @p message is set to contain a translated message for
+ * human consumption, describing the error.
+ */
+ static bool isRangeValid(const QDate &date,
+ QString &message);
+
+ protected:
+
+ /**
+ * @returns m_dateTime' zone offset converted to string, as per the
+ * the W3C XML Schema types. This is for
+ * example "Z" or "+12.00"(depending on m_dateTime).
+ */
+ QString zoneOffsetToString() const;
+
+ static QDateTime create(AtomicValue::Ptr &errorMessage,
+ const QString &lexicalSource,
+ const CaptureTable &captTable);
+
+ /**
+ * @short Makes the QDateTime::timeSpec() and QDateTime::zoneOffset()
+ * of @p ot * consistent to @p from.
+ */
+ static void copyTimeSpec(const QDateTime &from,
+ QDateTime &to);
+
+ const QDateTime m_dateTime;
+
+ private:
+ enum ZoneOffsetParseResult
+ {
+ /**
+ * syntax or logical error was encountered.
+ */
+ Error,
+ /**
+ * It's a valid offset from UTC.
+ */
+ Offset,
+
+ /**
+ * No zone offset was specified, it's an implementation defined zone offset.
+ */
+ LocalTime,
+ UTC
+ };
+
+ /**
+ * @short Parses the zone offset. All types use zone offsets.
+ *
+ * If result is set to Offset, the offset is returned, otherwise
+ * the return value is undefined.
+ *
+ * The offset is in seconds.
+ */
+ static ZOTotal parseZoneOffset(ZoneOffsetParseResult &result,
+ const QStringList &capts,
+ const CaptureTable &captTable);
+
+ static inline void setUtcOffset(QDateTime &result,
+ const ZoneOffsetParseResult zoResult,
+ const int zoOffset);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qabstractduration.cpp b/src/xmlpatterns/data/qabstractduration.cpp
new file mode 100644
index 0000000..6bd46c4
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractduration.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "qbuiltintypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qabstractduration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AbstractDuration::AbstractDuration(const bool isPos) : m_isPositive(isPos)
+{
+}
+
+#define error(msg) return ValidationError::createError(msg);
+#define getCapt(sym) ((captTable.sym == -1) ? QString() : capts.at(captTable.sym))
+
+AtomicValue::Ptr AbstractDuration::create(const CaptureTable &captTable,
+ const QString &lexical,
+ bool *isPositive,
+ YearProperty *years,
+ MonthProperty *months,
+ DayCountProperty *days,
+ HourProperty *hours,
+ MinuteProperty *minutes,
+ SecondProperty *seconds,
+ MSecondProperty *mseconds)
+{
+ /* We don't directly write into the arguments(eg @p years) but uses these
+ * because the arguments are intended for normalized values, and therefore
+ * can cause overflows. */
+ MonthCountProperty monthCount = 0;
+ MinuteCountProperty minCount = 0;
+ HourCountProperty hourCount = 0;
+ SecondCountProperty secCount = 0;
+
+ Q_ASSERT(isPositive);
+ QRegExp myExp(captTable.regExp); /* Copy, in order to stay thread safe. */
+
+ if(!myExp.exactMatch(lexical))
+ {
+ error(QString());
+ }
+
+ const QStringList capts(myExp.capturedTexts());
+
+
+ if(days)
+ {
+ if(getCapt(tDelimiter).isEmpty())
+ {
+ if((years && getCapt(year).isEmpty() && getCapt(month).isEmpty() && getCapt(day).isEmpty())
+ ||
+ (!years && getCapt(day).isEmpty()))
+ {
+ error(QtXmlPatterns::tr("At least one component must be present."));
+ }
+ }
+ else if(getCapt(hour).isEmpty() &&
+ getCapt(minutes).isEmpty() &&
+ getCapt(seconds).isEmpty() &&
+ getCapt(mseconds).isEmpty())
+ {
+ error(QtXmlPatterns::tr("At least one time component must appear "
+ "after the %1-delimiter.")
+ .arg(formatKeyword("T")));
+ }
+ }
+ else if(getCapt(year).isEmpty() && getCapt(month).isEmpty()) /* This checks xs:yearMonthDuration. */
+ {
+ error(QtXmlPatterns::tr("At least one component must be present."));
+ }
+
+ /* If we got no '-', we are positive. */
+ *isPositive = capts.at(1).isEmpty();
+
+ if(days)
+ {
+ Q_ASSERT(hours);
+ Q_ASSERT(minutes);
+ Q_ASSERT(seconds);
+ Q_ASSERT(mseconds);
+
+ *days = getCapt(day).toInt();
+ hourCount = getCapt(hour).toInt();
+ minCount = getCapt(minutes).toInt();
+ secCount = getCapt(seconds).toInt();
+
+ const QString msecondsStr(getCapt(mseconds));
+ if(!msecondsStr.isEmpty())
+ *mseconds = msecondsStr.leftJustified(3, QLatin1Char('0')).toInt();
+ else
+ *mseconds = msecondsStr.toInt();
+
+ if(secCount > 59)
+ {
+ minCount += secCount / 60;
+ *seconds = secCount % 60;
+ }
+ else
+ *seconds = secCount;
+
+ if(minCount > 59)
+ {
+ hourCount += minCount / 60;
+ *minutes = minCount % 60;
+ }
+ else
+ *minutes = minCount;
+
+ if(hourCount > 23)
+ {
+ *days += hourCount / 24;
+ *hours = hourCount % 24;
+ }
+ else
+ *hours = hourCount;
+ }
+
+ if(!years)
+ return AtomicValue::Ptr();
+
+ /* We're supposed to handle years/months. */
+ Q_ASSERT(months);
+
+ *years = getCapt(year).toInt();
+ monthCount = getCapt(month).toInt();
+
+ if(monthCount > 11)
+ {
+ *years += monthCount / 12;
+ *months = monthCount % 12;
+ }
+ else
+ *months = monthCount;
+
+ return AtomicValue::Ptr();
+}
+#undef error
+#undef getCapt
+
+bool AbstractDuration::operator==(const AbstractDuration &other) const
+{
+ if(years() == other.years()
+ && months() == other.months()
+ && days() == other.days()
+ && hours() == other.hours()
+ && minutes() == other.minutes()
+ && seconds() == other.seconds()
+ && mseconds() == other.mseconds())
+ {
+ if(isPositive() == other.isPositive())
+ return true;
+ else if(years() == 0
+ && months() == 0
+ && days() == 0
+ && hours() == 0
+ && minutes() == 0
+ && seconds () == 0
+ && mseconds() == 0)
+ {
+ return true; /* Signedness doesn't matter if all are zero. */
+ }
+ }
+
+ return false;
+}
+
+QString AbstractDuration::serializeMSeconds(const MSecondProperty mseconds)
+{
+ QString retval;
+ retval.append(QLatin1Char('.'));
+ int div = 100;
+ MSecondProperty msecs = mseconds;
+
+ while(msecs > 0)
+ {
+ int d = msecs / div;
+ retval.append(QLatin1Char(d + '0'));
+ msecs = msecs % div;
+ div = div / 10;
+ }
+
+ return retval;
+}
+
+bool AbstractDuration::isPositive() const
+{
+ return m_isPositive;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qabstractduration_p.h b/src/xmlpatterns/data/qabstractduration_p.h
new file mode 100644
index 0000000..adde9d5
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractduration_p.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AbstractDuration_H
+#define Patternist_AbstractDuration_H
+
+#include <QRegExp>
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for classes implementing durations.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#duration">XML Schema Part
+ * 2: Datatypes Second Edition, 3.2.6 duration</a>
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/#dates-and-times">XQuery
+ * 1.0 and XPath 2.0 Data Model (XDM), 3.3.2 Dates and Times</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo Documentation is missing/incomplete
+ */
+ class AbstractDuration : public AtomicValue
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AbstractDuration> Ptr;
+
+ /**
+ * @short The amount in milli seconds.
+ */
+ typedef qint64 Value;
+
+ /**
+ * @short Acts as a mapping table for AbstractDuration::create()
+ * and describes where certain fields in a QRegExp pattern can be found
+ * for a particular W3C XML Schema duration type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class CaptureTable
+ {
+ public:
+ CaptureTable(const QRegExp &exp,
+ const qint8 yearP,
+ const qint8 monthP,
+ const qint8 dayP = -1,
+ const qint8 tDelimiterP = -1,
+ const qint8 hourP = -1,
+ const qint8 minutesP = -1,
+ const qint8 secondsP = -1,
+ const qint8 msecondsP = -1) : regExp(exp),
+ year(yearP),
+ month(monthP),
+ day(dayP),
+ tDelimiter(tDelimiterP),
+ hour(hourP),
+ minutes(minutesP),
+ seconds(secondsP),
+ mseconds(msecondsP)
+ {
+ Q_ASSERT(exp.isValid());
+ Q_ASSERT(yearP == -1 || yearP == 2);
+ }
+
+ const QRegExp regExp;
+ const qint8 year;
+ const qint8 month;
+ const qint8 day;
+ const qint8 tDelimiter;
+ const qint8 hour;
+ const qint8 minutes;
+ const qint8 seconds;
+ const qint8 mseconds;
+ };
+
+ /**
+ * Determines whether this Duration is equal to @p other.
+ *
+ * @note Do not re-implement this function. It uses getters such as years() and
+ * mseconds() for determining its truth value.
+ */
+ bool operator==(const AbstractDuration &other) const;
+
+ virtual YearProperty years() const = 0;
+ virtual MonthProperty months() const = 0;
+ virtual DayCountProperty days() const = 0;
+ virtual HourProperty hours() const = 0;
+ virtual MinuteProperty minutes() const = 0;
+ virtual SecondProperty seconds() const = 0;
+ virtual MSecondProperty mseconds() const = 0;
+
+ /**
+ * @returns the value of this AbstractDuration. For example,
+ * in the case of xs:yearMonthDuration, that is YearMonthDuration,
+ * years times twelve plus the months is returned.
+ */
+ virtual Value value() const = 0;
+
+ /**
+ * A polymorphic factory function that returns instances of the
+ * sub-class with the value @p val.
+ */
+ virtual Item fromValue(const Value val) const = 0;
+
+ /**
+ * Determines whether this AbstractDuration is positive. For example,
+ * "P10H" is positive, while "-P10H" is not.
+ *
+ * @note Do not re-implement this function. Use the constructor, AbstractDuration(),
+ * for changing the value.
+ * @returns @c true if this AbstractDuration is positive, otherwise @c false.
+ */
+ bool isPositive() const;
+
+ protected:
+
+ AbstractDuration(const bool isPos);
+
+ static QString serializeMSeconds(const MSecondProperty mseconds);
+ static AtomicValue::Ptr create(const CaptureTable &captTable,
+ const QString &lexical,
+ bool *isPositive,
+ YearProperty *years,
+ MonthProperty *months,
+ DayCountProperty *days,
+ HourProperty *hours,
+ MinuteProperty *minutes,
+ SecondProperty *seconds,
+ MSecondProperty *mseconds);
+ const bool m_isPositive;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qabstractfloat.cpp b/src/xmlpatterns/data/qabstractfloat.cpp
new file mode 100644
index 0000000..4f0c175
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloat.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qabstractfloat_p.h.
+ * If you need includes in this file, put them in qabstractfloat_p.h, outside of the namespace.
+ */
+
+template <const bool isDouble>
+AbstractFloat<isDouble>::AbstractFloat(const xsDouble num) : m_value(num)
+{
+}
+
+template <const bool isDouble>
+Numeric::Ptr AbstractFloat<isDouble>::fromValue(const xsDouble num)
+{
+ return Numeric::Ptr(new AbstractFloat<isDouble>(num));
+}
+
+template <const bool isDouble>
+AtomicValue::Ptr AbstractFloat<isDouble>::fromLexical(const QString &strNumeric)
+{
+ /* QString::toDouble() handles the whitespace facet. */
+
+ if(strNumeric == QLatin1String("NaN"))
+ return isDouble ? CommonValues::DoubleNaN : CommonValues::FloatNaN;
+ else if(strNumeric == QLatin1String("-INF"))
+ return isDouble ? CommonValues::NegativeInfDouble : CommonValues::NegativeInfFloat;
+ else if(strNumeric == QLatin1String("INF"))
+ return isDouble ? CommonValues::InfDouble : CommonValues::InfFloat;
+
+ /* QString::toDouble() supports any case as well as +INF, but we don't. */
+ const QString toUpper(strNumeric.toUpper());
+ if(toUpper == QLatin1String("-INF") ||
+ toUpper == QLatin1String("INF") ||
+ toUpper == QLatin1String("+INF") ||
+ toUpper == QLatin1String("NAN"))
+ {
+ return ValidationError::createError();
+ }
+
+ bool conversionOk = false;
+ const xsDouble num = strNumeric.toDouble(&conversionOk);
+
+ if(conversionOk)
+ return AtomicValue::Ptr(new AbstractFloat<isDouble>(num));
+ else
+ return ValidationError::createError();
+}
+
+template <const bool isDouble>
+int AbstractFloat<isDouble>::internalSignbit(const xsDouble num)
+{
+ Q_ASSERT_X(sizeof(xsDouble) == 8 || sizeof(xsDouble) == 4, Q_FUNC_INFO,
+ "This implementation of signbit assumes xsDouble, that is qreal, is 64 bits large.");
+
+ union
+ {
+ xsDouble asDouble;
+ qint64 asInt;
+ } value;
+
+ value.asDouble = num;
+
+ /* The highest bit, the 64'th for those who have 64bit floats, is the sign bit. So we pull it down until that bit is the
+ * only one left. */
+ if(sizeof(xsDouble) == 8)
+ return value.asInt >> 63;
+ else
+ return value.asInt >> 31;
+}
+
+template <const bool isDouble>
+bool AbstractFloat<isDouble>::isEqual(const xsDouble a, const xsDouble b)
+{
+ if(qIsInf(a))
+ return qIsInf(b) && internalSignbit(a) == internalSignbit(b);
+ else if(qIsInf(b))
+ return qIsInf(a) && internalSignbit(a) == internalSignbit(b);
+ else
+ {
+ /* Preferably, we would use std::numeric_limits<xsDouble>::espilon(), but
+ * we cannot since we cannot depend on the STL. The small xs:double value below,
+ * was extracted by printing the std::numeric_limits<xsDouble>::epsilon() using
+ * gdb. */
+ return qAbs(a - b) <= 2.2204460492503131e-16 * qAbs(a);
+ }
+}
+
+template <const bool isDouble>
+bool AbstractFloat<isDouble>::isZero() const
+{
+ return AbstractFloat<isDouble>::isEqual(m_value, 0.0);
+}
+
+template <const bool isDouble>
+bool AbstractFloat<isDouble>::evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ if(isZero() || qIsNaN(m_value))
+ return false;
+ else
+ return true;
+}
+
+template <const bool isDouble>
+QString AbstractFloat<isDouble>::stringValue() const
+{
+ if(qIsNaN(m_value))
+ return QLatin1String("NaN");
+ else if(qIsInf(m_value))
+ return internalSignbit(m_value) == 0 ? QLatin1String("INF") : QLatin1String("-INF");
+ /*
+ * If SV has an absolute value that is greater than or equal to 0.000001
+ * (one millionth) and less than 1000000 (one million),
+ * then the value is converted to an xs:decimal and the resulting xs:decimal
+ * is converted to an xs:string according to the rules above.
+ */
+ else if(0.000001 <= qAbs(m_value) && qAbs(m_value) < 1000000.0)
+ return Decimal::toString(toDecimal());
+ /*
+ * If SV has the value positive or negative zero, TV is "0" or "-0" respectively.
+ */
+ else if(isZero())
+ return internalSignbit(m_value) == 0 ? QLatin1String("0") : QLatin1String("-0");
+ else
+ {
+ /*
+ * Besides these special values, the general form of the canonical form for
+ * xs:float and xs:double is a mantissa, which is a xs:decimal, followed by
+ * the letter "E", followed by an exponent which is an xs:integer.
+ */
+ int sign;
+ int decimalPoint;
+ char *result = 0;
+ static_cast<void>(qdtoa(m_value, -1, 0, &decimalPoint, &sign, 0, &result));
+
+ /* If the copy constructor is used instead of QString::operator=(),
+ * it doesn't compile. I have no idea why. */
+ const QString qret(QString::fromLatin1(result));
+
+ /* We use free() instead of delete here, because qlocale.cpp use malloc(). Spotted
+ * by valgrind. */
+ free(result);
+
+ QString valueAsString;
+
+ if(sign)
+ valueAsString += QLatin1Char('-');
+
+ valueAsString += qret.at(0);
+ valueAsString += QLatin1Char('.');
+
+ if(1 == qret.size())
+ valueAsString += QLatin1Char('0');
+ else
+ valueAsString += qret.mid(1);
+
+ valueAsString += QLatin1Char('E');
+ decimalPoint--;
+ valueAsString += QString::number(decimalPoint);
+ return valueAsString;
+ }
+}
+
+template <const bool isDouble>
+xsDouble AbstractFloat<isDouble>::toDouble() const
+{
+ return m_value;
+}
+
+template <const bool isDouble>
+xsInteger AbstractFloat<isDouble>::toInteger() const
+{
+ return static_cast<xsInteger>(m_value);
+}
+
+template <const bool isDouble>
+xsFloat AbstractFloat<isDouble>::toFloat() const
+{
+ /* No cast, since xsFloat and xsDouble are typedef'ed with the same type. */
+ return m_value;
+}
+
+template <const bool isDouble>
+xsDecimal AbstractFloat<isDouble>::toDecimal() const
+{
+ return static_cast<xsDecimal>(m_value);
+}
+
+template <const bool isDouble>
+Numeric::Ptr AbstractFloat<isDouble>::round() const
+{
+ return AbstractFloat<isDouble>::fromValue(static_cast<xsDouble>(roundFloat(m_value)));
+}
+
+template <const bool isDouble>
+Numeric::Ptr AbstractFloat<isDouble>::roundHalfToEven(const xsInteger precision) const
+{
+ if(isNaN() || isInf() || isZero())
+ return Numeric::Ptr(const_cast<AbstractFloat<isDouble> *>(this));
+ else
+ {
+ /* The cast to double helps finding the correct pow() version on irix-cc. */
+ const xsDouble powered = pow(double(10), double(precision));
+ xsDouble val = powered * m_value;
+ bool isHalf = false;
+
+ if(val - 0.5 == ::floor(val))
+ isHalf = true;
+
+ val = m_value * powered + 0.5;
+ val = ::floor(val);
+
+ if(isHalf /*&& isOdd(val) or? TODO */)
+ val -= 1;
+
+ val /= powered;
+
+ return fromValue(val);
+ }
+}
+
+template <const bool isDouble>
+Numeric::Ptr AbstractFloat<isDouble>::floor() const
+{
+ return AbstractFloat<isDouble>::fromValue(static_cast<xsDouble>(::floor(m_value)));
+}
+
+template <const bool isDouble>
+Numeric::Ptr AbstractFloat<isDouble>::ceiling() const
+{
+ return AbstractFloat<isDouble>::fromValue(static_cast<xsDouble>(ceil(m_value)));
+}
+
+template <const bool isDouble>
+Numeric::Ptr AbstractFloat<isDouble>::abs() const
+{
+ /* We must use fabs() instead of qAbs() because qAbs()
+ * doesn't return 0 for -0.0. */
+ return AbstractFloat<isDouble>::fromValue(static_cast<xsDouble>(fabs(m_value)));
+}
+
+template <const bool isDouble>
+bool AbstractFloat<isDouble>::isNaN() const
+{
+ return qIsNaN(m_value);
+}
+
+template <const bool isDouble>
+bool AbstractFloat<isDouble>::isInf() const
+{
+ return qIsInf(m_value);
+}
+
+template <const bool isDouble>
+ItemType::Ptr AbstractFloat<isDouble>::type() const
+{
+ return isDouble ? BuiltinTypes::xsDouble : BuiltinTypes::xsFloat;
+}
+
+template <const bool isDouble>
+Item AbstractFloat<isDouble>::toNegated() const
+{
+ return fromValue(-m_value).data();
+}
+
+template <const bool isDouble>
+bool AbstractFloat<isDouble>::isSigned() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function, see Numeric::isSigned().");
+ return false;
+}
+
+template <const bool isDouble>
+qulonglong AbstractFloat<isDouble>::toUnsignedInteger() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function, see Numeric::toUnsignedInteger().");
+ return 0;
+}
+
diff --git a/src/xmlpatterns/data/qabstractfloat_p.h b/src/xmlpatterns/data/qabstractfloat_p.h
new file mode 100644
index 0000000..9abf97f
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloat_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AbstractFloat_H
+#define Patternist_AbstractFloat_H
+
+#include <math.h>
+
+#include <qnumeric.h>
+
+#include "qcommonvalues_p.h"
+#include "qdecimal_p.h"
+#include "qschemanumeric_p.h"
+#include "qvalidationerror_p.h"
+#include "qbuiltintypes_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base template class for Float and Double classes.
+ *
+ * @author Vincent Ricard <magic@magicninja.org>
+ * @ingroup Patternist_xdm
+ */
+ template <const bool isDouble>
+ class AbstractFloat : public Numeric
+ {
+ public:
+ static Numeric::Ptr fromValue(const xsDouble num);
+ static AtomicValue::Ptr fromLexical(const QString &strNumeric);
+
+ /**
+ * @todo more extensive docs.
+ *
+ * Performs floating point comparison.
+ *
+ * @returns @c true if @p a and @p are equal, otherwise @c false.
+ */
+ static bool isEqual(const xsDouble a, const xsDouble b);
+
+ /**
+ * Determines the Effective %Boolean Value of this number.
+ *
+ * @returns @c false if the number is 0 or @c NaN, otherwise @c true.
+ */
+ bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const;
+
+ /**
+ * Returns this AbstractFloat represented as an @c xs:string.
+ *
+ * @note In the XPath/XQuery languages, converting @c xs:double and @c xs:float
+ * to @c xs:string is not specified in XML Schema 1.0 Part 2: Datatypes Second Edition,
+ * but in XQuery 1.0 and XPath 2.0 Functions and Operators. This will change with W3C XML
+ * Schema 1.1
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#casting-to-string">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 17.1.2 Casting to xs:string and xdt:untypedAtomic</a>
+ */
+ virtual QString stringValue() const;
+
+ virtual xsDouble toDouble() const;
+ virtual xsInteger toInteger() const;
+ virtual xsFloat toFloat() const;
+ virtual xsDecimal toDecimal() const;
+
+ virtual Numeric::Ptr round() const;
+ virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const;
+ virtual Numeric::Ptr floor() const;
+ virtual Numeric::Ptr ceiling() const;
+ virtual Numeric::Ptr abs() const;
+
+ virtual bool isNaN() const;
+ virtual bool isInf() const;
+
+ virtual ItemType::Ptr type() const;
+ virtual Item toNegated() const;
+ virtual qulonglong toUnsignedInteger() const;
+
+ virtual bool isSigned() const;
+ protected:
+ AbstractFloat(const xsDouble num);
+
+ private:
+ /**
+ * From the Open Group's man page: "The signbit() macro shall return a
+ * non-zero value if and only if the sign of its argument value is
+ * negative."
+ *
+ * MS Windows doesn't have std::signbit() so here's
+ * a reinvention of that function.
+ */
+ static inline int internalSignbit(const xsDouble v);
+ inline bool isZero() const;
+
+ const xsDouble m_value;
+ };
+
+ template <const bool isDouble>
+ Numeric::Ptr createFloat(const xsDouble num);
+
+#include "qabstractfloat.cpp"
+
+ /**
+ * @short An instantiation of AbsbstractFloat suitable for @c xs:double.
+ *
+ * @ingroup Patternist_xdm
+ */
+ typedef AbstractFloat<true> Double;
+
+ /**
+ * @short An instantiation of AbstractFloat suitable for @c xs:float.
+ *
+ * @ingroup Patternist_xdm
+ */
+ typedef AbstractFloat<false> Float;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qabstractfloatcasters.cpp b/src/xmlpatterns/data/qabstractfloatcasters.cpp
new file mode 100644
index 0000000..394d732
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatcasters.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * NOTE: This file is included by qabstractfloatcasters_p.h
+ * if you need some includes, put them in qabstractfloatcasters_p.h (outside of the namespace)
+ */
+
+template <const bool isDouble>
+Item NumericToAbstractFloatCaster<isDouble>::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ // toDouble() returns same thing than toFloat()
+ return toItem(AbstractFloat<isDouble>::fromValue(from.template as<Numeric>()->toDouble()));
+}
+
+template <const bool isDouble>
+Item StringToAbstractFloatCaster<isDouble>::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return toItem(AbstractFloat<isDouble>::fromLexical(from.stringValue()));
+}
+
+template <const bool isDouble>
+Item BooleanToAbstractFloatCaster<isDouble>::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is
+ // passed directly into another constructor.
+ bool tempDouble = isDouble;
+ if(from.template as<AtomicValue>()->evaluateEBV(context))
+ return tempDouble ? toItem(CommonValues::DoubleOne) : toItem(CommonValues::FloatOne);
+ else
+ return tempDouble ? toItem(CommonValues::DoubleZero) : toItem(CommonValues::FloatZero);
+}
+
diff --git a/src/xmlpatterns/data/qabstractfloatcasters_p.h b/src/xmlpatterns/data/qabstractfloatcasters_p.h
new file mode 100644
index 0000000..109018c
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatcasters_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AbstractFloatCasters_H
+#define Patternist_AbstractFloatCasters_H
+
+#include "qabstractfloat_p.h"
+#include "qatomiccaster_p.h"
+#include "qschemanumeric_p.h"
+
+/**
+ * @file
+ * @short Contains classes sub-classing AtomicCaster and which
+ * are responsible of casting an atomic value to AbstractFloat.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Casts a @c numeric value, such as @c xs:integer or @c xs:float, to @c xs:double or xs:float.
+ *
+ * castFrom() uses Numeric::toDouble() for doing the actual casting.
+ *
+ * @ingroup Patternist_xdm
+ * @author Vincent Ricard <magic@magicninja.org>
+ */
+ template <const bool isDouble>
+ class NumericToAbstractFloatCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:double or xs:float.
+ *
+ * @ingroup Patternist_xdm
+ * @author Vincent Ricard <magic@magicninja.org>
+ */
+ template <const bool isDouble>
+ class StringToAbstractFloatCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a value of type @c xs:boolean to @c xs:double or xs:float.
+ *
+ * @ingroup Patternist_xdm
+ * @author Vincent Ricard <magic@magicninja.org>
+ */
+ template <const bool isDouble>
+ class BooleanToAbstractFloatCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+#include "qabstractfloatcasters.cpp"
+
+ /**
+ * @short Casts a @c numeric value, such as @c xs:integer or @c xs:float, to @c xs:double.
+ *
+ * castFrom() uses Numeric::toDouble() for doing the actual casting.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ typedef NumericToAbstractFloatCaster<true> NumericToDoubleCaster;
+
+ /**
+ * @short Casts a @c numeric value, such as @c xs:double or @c xs:decimal, to @c xs:float.
+ *
+ * castFrom() uses Numeric::toFloat() for doing the actual casting.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ typedef NumericToAbstractFloatCaster<false> NumericToFloatCaster;
+
+ /**
+ * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:double.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ typedef StringToAbstractFloatCaster<true> StringToDoubleCaster;
+
+ /**
+ * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:float.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ typedef StringToAbstractFloatCaster<false> StringToFloatCaster;
+
+ /**
+ * @short Casts a value of type @c xs:boolean to @c xs:double.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ typedef BooleanToAbstractFloatCaster<true> BooleanToDoubleCaster;
+
+ /**
+ * @short Casts a value of type @c xs:boolean to @c xs:float.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ typedef BooleanToAbstractFloatCaster<false> BooleanToFloatCaster;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qabstractfloatmathematician.cpp b/src/xmlpatterns/data/qabstractfloatmathematician.cpp
new file mode 100644
index 0000000..94507b3
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatmathematician.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * @file
+ * @short This file is included by qatomicmathematicians_p.h
+ * if you need some includes, put them in qabstractfloatmathematician_p.h, outside of the namespace.
+ */
+
+template <const bool isDouble>
+Item AbstractFloatMathematician<isDouble>::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ const Numeric *const num1 = o1.template as<Numeric>();
+ const Numeric *const num2 = o2.template as<Numeric>();
+ switch(op)
+ {
+ case Div:
+ return toItem(AbstractFloat<isDouble>::fromValue(num1->toDouble() / num2->toDouble()));
+ case IDiv:
+ {
+ if(num1->isNaN() || num2->isNaN())
+ {
+ context->error(QtXmlPatterns::tr("No operand in an integer division, %1, can be %2.")
+ .arg(formatKeyword("idiv"))
+ .arg(formatData("NaN")),
+ ReportContext::FOAR0002, this);
+ }
+ else if(num1->isInf())
+ {
+ context->error(QtXmlPatterns::tr("The first operand in an integer division, %1, cannot be infinity (%2).")
+ .arg(formatKeyword("idiv"))
+ .arg(formatData("INF")),
+ ReportContext::FOAR0002, this);
+ }
+ else if(num2->toInteger() == 0)
+ context->error(QtXmlPatterns::tr("The second operand in a division, %1, cannot be zero (%2).")
+ .arg(formatKeyword("idiv"))
+ .arg(formatData("0")),
+ ReportContext::FOAR0001, this);
+
+ return Integer::fromValue(static_cast<xsInteger>(num1->toDouble() / num2->toDouble()));
+ }
+ case Substract:
+ return toItem(AbstractFloat<isDouble>::fromValue(num1->toDouble() - num2->toDouble()));
+ case Mod:
+ return toItem(AbstractFloat<isDouble>::fromValue(::fmod(num1->toDouble(), num2->toDouble())));
+ case Multiply:
+ return toItem(AbstractFloat<isDouble>::fromValue(num1->toDouble() * num2->toDouble()));
+ case Add:
+ return toItem(AbstractFloat<isDouble>::fromValue(num1->toDouble() + num2->toDouble()));
+ }
+
+ Q_ASSERT(false);
+ return Item(); /* GCC unbarfer. */
+}
+
diff --git a/src/xmlpatterns/data/qabstractfloatmathematician_p.h b/src/xmlpatterns/data/qabstractfloatmathematician_p.h
new file mode 100644
index 0000000..a51934a
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatmathematician_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AbstractFloatMathematician_H
+#define Patternist_AbstractFloatMathematician_H
+
+#include "qabstractfloat_p.h"
+#include "qatomicmathematician_p.h"
+#include "qinteger_p.h"
+#include "qschemanumeric_p.h"
+#include "qpatternistlocale_p.h"
+#include "qsourcelocationreflection_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Performs arithmetics between AbstractFloat values (Float and Double classes).
+ *
+ * @ingroup Patternist_xdm
+ * @author Vincent Ricard <magic@magicninja.org>
+ */
+ template <const bool isDouble>
+ class AbstractFloatMathematician : public AtomicMathematician
+ , public DelegatingSourceLocationReflection
+ {
+ public:
+ inline AbstractFloatMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r)
+ {
+ }
+
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+#include "qabstractfloatmathematician.cpp"
+
+ /**
+ * An instantiation of AbstractFloatMathematician that handles @c xs:double.
+ */
+ typedef AbstractFloatMathematician<true> DoubleMathematician;
+
+ /**
+ * An instantiation of AbstractFloatMathematician that handles @c xs:float.
+ */
+ typedef AbstractFloatMathematician<false> FloatMathematician;
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qanyuri.cpp b/src/xmlpatterns/data/qanyuri.cpp
new file mode 100644
index 0000000..5d50efc
--- /dev/null
+++ b/src/xmlpatterns/data/qanyuri.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdynamiccontext_p.h"
+#include "qvalidationerror_p.h"
+#include "qitem_p.h"
+
+#include "qanyuri_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AnyURI::AnyURI(const QString &s) : AtomicString(s)
+{
+}
+
+AnyURI::Ptr AnyURI::fromValue(const QString &value)
+{
+ return AnyURI::Ptr(new AnyURI(value));
+}
+
+AnyURI::Ptr AnyURI::fromValue(const QUrl &uri)
+{
+ return AnyURI::Ptr(new AnyURI(uri.toString()));
+}
+
+AnyURI::Ptr AnyURI::resolveURI(const QString &relative,
+ const QString &base)
+{
+ const QUrl urlBase(base);
+ return AnyURI::fromValue(urlBase.resolved(relative).toString());
+}
+
+ItemType::Ptr AnyURI::type() const
+{
+ return BuiltinTypes::xsAnyURI;
+}
+
+AnyURI::Ptr AnyURI::fromLexical(const QString &value)
+{
+ bool isValid;
+ /* The error code doesn't matter, because we never raise error. */
+ const QUrl retval(toQUrl<ReportContext::FORG0001>(value,
+ DynamicContext::Ptr(),
+ 0,
+ &isValid,
+ false));
+ if(isValid)
+ return fromValue(retval);
+ else
+ return ValidationError::createError();
+}
+
+bool AnyURI::isValid(const QString &candidate)
+{
+ bool isOk = false;
+ /* The error code doesn't matter, because we never raise error. */
+ toQUrl<ReportContext::FORG0001>(candidate,
+ ReportContext::Ptr(),
+ 0,
+ &isOk,
+ false);
+ return isOk;
+}
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qanyuri_p.h b/src/xmlpatterns/data/qanyuri_p.h
new file mode 100644
index 0000000..6567d9c
--- /dev/null
+++ b/src/xmlpatterns/data/qanyuri_p.h
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AnyURI_H
+#define Patternist_AnyURI_H
+
+#include <QUrl>
+#include <QtDebug>
+
+#include "qatomicstring_p.h"
+#include "qbuiltintypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qreportcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A value of type <tt>xs:anyURI</tt>.
+ *
+ * Due to bugs in QUrl and slight differences in behavior and
+ * interpretation, QUrl can never be used directly for dealing with URIs,
+ * values of type @c xs:anyURI. Therefore, it's important to use the
+ * functionality this class provides, such as the functions toQUrl(),
+ * fromLexical(), isValid(), and resolveURI().
+ *
+ * @see QUrl
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class AnyURI : public AtomicString
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AnyURI> Ptr;
+
+ /**
+ * Creates an instance representing @p value.
+ *
+ * @note @p value must be a valid @c xs:anyURI. If it is of interest
+ * to construct from a lexical representation, use fromLexical().
+ */
+ static AnyURI::Ptr fromValue(const QString &value);
+
+ static AnyURI::Ptr fromValue(const QUrl &uri);
+
+ /**
+ * @short Treates @p value as a lexical representation of @c xs:anyURI
+ * but returns the value instance as a QUrl.
+ *
+ * If @p value is not a valid lexical representation of @c xs:anyURI,
+ * an error is issued via @p context.
+ *
+ * If @p isValid is passed, no error is raised and it is instead set
+ * appropriately.
+ */
+ template<const ReportContext::ErrorCode code, typename TReportContext>
+ static inline QUrl toQUrl(const QString &value,
+ const TReportContext &context,
+ const SourceLocationReflection *const r,
+ bool *const isValid = 0,
+ const bool issueError = true)
+ {
+ /* QUrl doesn't flag ":/..." so we workaround it. */
+ const QString simplified(value.simplified());
+ const QUrl uri(simplified, QUrl::StrictMode);
+
+ if(uri.isEmpty() || (uri.isValid() && (!simplified.startsWith(QLatin1Char(':')) || !uri.isRelative())))
+ {
+ if(isValid)
+ *isValid = true;
+
+ return uri;
+ }
+ else
+ {
+ if(isValid)
+ *isValid = false;
+
+ if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("%1 is not a valid value of type %2.").arg(formatURI(value), formatType(context->namePool(), BuiltinTypes::xsAnyURI)),
+ code, r);
+ }
+
+ return QUrl();
+ }
+ }
+
+ /**
+ * @short Return @c true if @p candidate is a valid @c xs:anyURI,
+ * otherwise @c false.
+ */
+ static bool isValid(const QString &candidate);
+
+ /**
+ * @short Constructs a @c xs:anyURI value from the lexical representation @p value.
+ *
+ * If @p value is not a valid lexical representation of @c xs:anyURI,
+ * an error is issued via @p context.
+ */
+ template<const ReportContext::ErrorCode code, typename TReportContext>
+ static inline AnyURI::Ptr fromLexical(const QString &value,
+ const TReportContext &context,
+ const SourceLocationReflection *const r)
+ {
+ return AnyURI::Ptr(new AnyURI(toQUrl<code>(value, context, r).toString()));
+ }
+
+ /**
+ * If @p value is not a valid lexical representation for @c xs:anyURI,
+ * a ValidationError is returned.
+ */
+ static AnyURI::Ptr fromLexical(const QString &value);
+
+ /**
+ * Creates an AnyURI instance representing an absolute URI which
+ * is created from resolving @p relative against @p base.
+ *
+ * This function must be compatible with the resolution semantics
+ * specified for fn:resolve-uri. In fact, the implementation of fn:resolve-uri,
+ * ResourceURIFN, relies on this function.
+ *
+ * @see <a href="http://www.faqs.org/rfcs/rfc3986.html">RFC 3986 - Uniform
+ * Resource Identifier (URI): Generic Syntax</a>
+ * @see <a href ="http://www.w3.org/TR/xpath-functions/#func-resolve-uri">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 8.1 fn:resolve-uri</a>
+ */
+ static AnyURI::Ptr resolveURI(const QString &relative,
+ const QString &base);
+
+ virtual ItemType::Ptr type() const;
+
+ /**
+ * @short Returns this @c xs:anyURI value in a QUrl.
+ */
+ inline QUrl toQUrl() const
+ {
+ Q_ASSERT_X(QUrl(m_value).isValid(), Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("%1 is apparently not ok for QUrl.").arg(m_value)));
+ return QUrl(m_value);
+ }
+ protected:
+ friend class CommonValues;
+
+ AnyURI(const QString &value);
+ };
+
+ /**
+ * @short Formats @p uri, that's considered to be a URI, for display.
+ */
+ static inline QString formatURI(const NamePool::Ptr &np, const QXmlName::NamespaceCode &uri)
+ {
+ return formatURI(np->stringForNamespace(uri));
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomiccaster.cpp b/src/xmlpatterns/data/qatomiccaster.cpp
new file mode 100644
index 0000000..20af624
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccaster.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomiccaster_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicCaster::AtomicCaster()
+{
+}
+
+AtomicCaster::~AtomicCaster()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qatomiccaster_p.h b/src/xmlpatterns/data/qatomiccaster_p.h
new file mode 100644
index 0000000..b746bc6
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccaster_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicCaster_H
+#define Patternist_AtomicCaster_H
+
+#include "qdynamiccontext_p.h"
+#include "qitem_p.h"
+#include "qatomictypedispatch_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short AtomicCaster is an abstract base class for classes
+ * that performs casting between two atomic values of specific types.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicCaster : public AtomicTypeVisitorResult
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AtomicCaster> Ptr;
+ AtomicCaster();
+ virtual ~AtomicCaster();
+
+ /**
+ * Casts @p from to an atomic value of the type this class
+ * casts to, and returns that value. The @p context is used
+ * for reporting errors in case the casting fails, and to in general
+ * access information from the dynamic context.
+ */
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomiccasters.cpp b/src/xmlpatterns/data/qatomiccasters.cpp
new file mode 100644
index 0000000..250641f
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccasters.cpp
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qnumeric.h>
+
+#include "qabstractfloat_p.h"
+#include "qanyuri_p.h"
+#include "qbase64binary_p.h"
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qdate_p.h"
+#include "qschemadatetime_p.h"
+#include "qdaytimeduration_p.h"
+#include "qdecimal_p.h"
+#include "qduration_p.h"
+#include "qgday_p.h"
+#include "qgmonth_p.h"
+#include "qgmonthday_p.h"
+#include "qgyear_p.h"
+#include "qgyearmonth_p.h"
+#include "qhexbinary_p.h"
+#include "qinteger_p.h"
+#include "qatomicstring_p.h"
+#include "qschematime_p.h"
+#include "quntypedatomic_p.h"
+#include "qyearmonthduration_p.h"
+
+#include "qatomiccasters_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ToUntypedAtomicCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return UntypedAtomic::fromValue(from.stringValue());
+}
+
+Item ToAnyURICaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return toItem(AnyURI::fromLexical(from.stringValue()));
+}
+
+Item Base64BinaryToHexBinaryCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return HexBinary::fromValue(from.as<Base64Binary>()->asByteArray());
+}
+
+Item StringToHexBinaryCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ return HexBinary::fromLexical(context->namePool(), from.stringValue());
+}
+
+Item HexBinaryToBase64BinaryCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return Base64Binary::fromValue(from.as<Base64Binary>()->asByteArray());
+}
+
+Item StringToBase64BinaryCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return Base64Binary::fromLexical(from.stringValue());
+}
+
+Item NumericToBooleanCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ const xsDouble val = from.as<Numeric>()->toDouble();
+ if(Double::isEqual(val, 0.0) || qIsNaN(val))
+ return CommonValues::BooleanFalse;
+ else
+ return CommonValues::BooleanTrue;
+}
+
+Item StringToBooleanCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return Boolean::fromLexical(from.stringValue());
+}
+
+Item StringToDecimalCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return Decimal::fromLexical(from.stringValue());
+}
+
+Item StringToIntegerCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return Integer::fromLexical(from.stringValue());
+}
+
+Item BooleanToDecimalCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ if(from.as<AtomicValue>()->evaluateEBV(context))
+ return CommonValues::DecimalOne;
+ else
+ return CommonValues::DecimalZero;
+}
+
+Item BooleanToIntegerCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ if(from.as<AtomicValue>()->evaluateEBV(context))
+ return CommonValues::IntegerOne;
+ else
+ return CommonValues::IntegerZero;
+}
+
+Item SelfToSelfCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return from;
+}
+
+Item StringToGYearCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return GYear::fromLexical(from.stringValue());
+}
+
+Item StringToGDayCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return GDay::fromLexical(from.stringValue());
+}
+
+Item StringToGMonthCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return GMonth::fromLexical(from.stringValue());
+}
+
+Item StringToGYearMonthCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return GYearMonth::fromLexical(from.stringValue());
+}
+
+Item StringToGMonthDayCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return GMonthDay::fromLexical(from.stringValue());
+}
+
+Item StringToDateTimeCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return DateTime::fromLexical(from.stringValue());
+}
+
+Item StringToTimeCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return SchemaTime::fromLexical(from.stringValue());
+}
+
+Item StringToDateCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return Date::fromLexical(from.stringValue());
+}
+
+Item StringToDurationCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return Duration::fromLexical(from.stringValue());
+}
+
+Item StringToDayTimeDurationCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return toItem(DayTimeDuration::fromLexical(from.stringValue()));
+}
+
+Item AbstractDurationToDayTimeDurationCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ const AbstractDuration *const val = from.as<AbstractDuration>();
+
+ return toItem(DayTimeDuration::fromComponents(val->isPositive(),
+ val->days(),
+ val->hours(),
+ val->minutes(),
+ val->seconds(),
+ val->mseconds()));
+}
+
+Item AbstractDurationToYearMonthDurationCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ const AbstractDuration *const val = from.as<AbstractDuration>();
+
+ return toItem(YearMonthDuration::fromComponents(val->isPositive(),
+ val->years(),
+ val->months()));
+}
+
+Item AbstractDurationToDurationCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ const AbstractDuration *const val = from.as<AbstractDuration>();
+
+ return Duration::fromComponents(val->isPositive(),
+ val->years(),
+ val->months(),
+ val->days(),
+ val->hours(),
+ val->minutes(),
+ val->seconds(),
+ val->mseconds());
+}
+
+Item StringToYearMonthDurationCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return YearMonthDuration::fromLexical(from.stringValue());
+}
+
+Item AbstractDateTimeToGYearCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(true);
+
+ return GYear::fromDateTime(dt);
+}
+
+Item AbstractDateTimeToGYearMonthCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(true);
+
+ return GYearMonth::fromDateTime(dt);
+}
+
+Item AbstractDateTimeToGMonthCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(true);
+
+ return GMonth::fromDateTime(dt);
+}
+
+Item AbstractDateTimeToGMonthDayCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(true);
+
+ return GMonthDay::fromDateTime(dt);
+}
+
+Item AbstractDateTimeToGDayCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(true);
+
+ return GDay::fromDateTime(dt);
+}
+
+Item AbstractDateTimeToDateTimeCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(false);
+
+ return DateTime::fromDateTime(dt);
+}
+
+Item AbstractDateTimeToDateCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(true);
+
+ return Date::fromDateTime(dt);
+}
+
+Item AbstractDateTimeToTimeCaster::castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ QDateTime dt(from.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(false);
+
+ return SchemaTime::fromDateTime(dt);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qatomiccasters_p.h b/src/xmlpatterns/data/qatomiccasters_p.h
new file mode 100644
index 0000000..d55344f
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccasters_p.h
@@ -0,0 +1,705 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicCasters_H
+#define Patternist_AtomicCasters_H
+
+#include "qatomiccaster_p.h"
+#include "qdecimal_p.h"
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qinteger_p.h"
+#include "qvalidationerror_p.h"
+
+/**
+ * @file
+ * @short Contains classes sub-classing AtomicCaster and which
+ * are responsible of casting an atomic value to another type.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Casts any atomic value to @c xs:string.
+ *
+ * This class uses Item::stringValue() for retrieving a string
+ * representation, and thus supports casting from atomic values
+ * of any type.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<TypeOfDerivedString DerivedType>
+ class ToStringCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+ {
+ Q_ASSERT(from);
+ return DerivedString<DerivedType>::fromLexical(context->namePool(), from.stringValue());
+ }
+ };
+
+ /**
+ * @short Casts any atomic value to @c xs:untypedAtomic.
+ *
+ * This class uses Item::stringValue() for retrieving a string
+ * representation, and thus supports casting from atomic values
+ * of any type. The implementation is similar to ToStringCaster.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToUntypedAtomicCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a string value to @c xs:anyURI.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToAnyURICaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:hexBinary atomic value to @c xs:base64Binary.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class HexBinaryToBase64BinaryCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:base64Binary atomic value to @c xs:hexBinary.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Base64BinaryToHexBinaryCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:base64Binary.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToBase64BinaryCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:hexBinary.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToHexBinaryCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts any @c numeric value to @c xs:boolean.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NumericToBooleanCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts any string value, @c xs:string or @c xs:untypedAtomic, to @c xs:boolean.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToBooleanCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c numeric value, such as @c xs:double or @c xs:decimal, to @c xs:integer or
+ * @c xs:decimal, depending on IsInteger.
+ *
+ * castFrom() uses Numeric::toInteger() for doing the actual casting.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template <const bool IsInteger>
+ class NumericToDecimalCaster : public AtomicCaster
+ {
+ public:
+ /**
+ * Used by NumericToDerivedIntegerCaster in addition to this class.
+ */
+ static inline QString errorMessage()
+ {
+ return QtXmlPatterns::tr("When casting to %1 from %2, the source value cannot be %3.");
+ }
+
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+ {
+ const ItemType::Ptr t(from.type());
+ const Numeric *const num = from.template as<Numeric>();
+
+ if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t))
+ {
+ if(num->isInf() || num->isNaN())
+ {
+ return ValidationError::createError(errorMessage()
+ .arg(formatType(context->namePool(), IsInteger ? BuiltinTypes::xsInteger : BuiltinTypes::xsDecimal))
+ .arg(formatType(context->namePool(), t))
+ .arg(formatData(num->stringValue())),
+ ReportContext::FOCA0002);
+ }
+ }
+
+ if(IsInteger)
+ return Integer::fromValue(num->toInteger());
+ else
+ return toItem(Decimal::fromValue(num->toDecimal()));
+ }
+ };
+
+ /**
+ * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:decimal.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToDecimalCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:integer.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToIntegerCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a value of type @c xs:boolean to @c xs:decimal.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BooleanToDecimalCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a value of type @c xs:boolean to @c xs:integer.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BooleanToIntegerCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a value to itself. Essentially, this AtomicCaster does nothing.
+ *
+ * Casting a value to the type of itself is defined to be a noop,
+ * no operation. When it can be statically detected that will be done,
+ * CastAs rewrites itself appropriately during compilation, but
+ * in some cases insufficent data is available at compile time and then
+ * is this class need on a case-per-case base at evaluation time.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SelfToSelfCaster : public AtomicCaster
+ {
+ public:
+
+ /**
+ * This function simply returns @p from.
+ */
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYear.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToGYearCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gDay.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToGDayCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gMonth.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToGMonthCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToGYearMonthCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToGMonthDayCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dateTime.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToDateTimeCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:time.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToTimeCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:date.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToDateCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:duration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToDurationCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dayTimeDuration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToDayTimeDurationCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:yearMonthDuration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringToYearMonthDurationCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+
+ /**
+ * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYear.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToGYearCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYearMonth.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToGYearMonthCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonth.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToGMonthCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonthDay.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToGMonthDayCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gDay.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToGDayCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts an AbstractDateTime instance to DateTime.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToDateTimeCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts an AbstractDateTime instance to SchemaTime.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToDateCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts an AbstractDateTime instance to SchemaTime.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeToTimeCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts an AbstractDuration instance to Duration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDurationToDurationCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts an AbstractDuration instance to DayTimeDuration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDurationToDayTimeDurationCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts an AbstractDuration instance to YearMonthDuration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDurationToYearMonthDurationCaster : public AtomicCaster
+ {
+ public:
+ virtual Item castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Casts an @c xs:string instance to a derived type of @c xs:integer.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<TypeOfDerivedInteger type>
+ class StringToDerivedIntegerCaster : public AtomicCaster
+ {
+ public:
+ virtual Item
+ castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+ {
+ return DerivedInteger<type>::fromLexical(context->namePool(), from.stringValue());
+ }
+ };
+
+ /**
+ * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<TypeOfDerivedInteger type>
+ class BooleanToDerivedIntegerCaster : public AtomicCaster
+ {
+ public:
+ virtual Item
+ castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+ {
+ return DerivedInteger<type>::fromValue(context->namePool(), from.template as<AtomicValue>()->evaluateEBV(context) ? 1 : 0);
+ }
+ };
+
+ /**
+ * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<TypeOfDerivedString type>
+ class AnyToDerivedStringCaster : public AtomicCaster
+ {
+ public:
+ virtual Item
+ castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+ {
+ return DerivedString<type>::fromLexical(context->namePool(), from.stringValue());
+ }
+ };
+
+ /**
+ * @short Casts any @c numeric instance to a derived type of @c xs:integer.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<TypeOfDerivedInteger type>
+ class NumericToDerivedIntegerCaster : public AtomicCaster
+ {
+ public:
+ virtual Item
+ castFrom(const Item &from,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+ {
+ const ItemType::Ptr t(from.type());
+ const Numeric *const num = from.template as<Numeric>();
+
+ if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t))
+ {
+ if(num->isInf() || num->isNaN())
+ {
+ return ValidationError::createError(NumericToDecimalCaster<false>::errorMessage()
+ .arg(formatType(context->namePool(), DerivedInteger<type>::itemType()))
+ .arg(formatType(context->namePool(), t))
+ .arg(formatData(num->stringValue())),
+ ReportContext::FOCA0002);
+ }
+ }
+
+ return toItem(DerivedInteger<type>::fromValue(context->namePool(), from.template as<Numeric>()->toInteger()));
+ }
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomiccomparator.cpp b/src/xmlpatterns/data/qatomiccomparator.cpp
new file mode 100644
index 0000000..c0bf3b9
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparator.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+
+#include "qatomiccomparator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicComparator::AtomicComparator()
+{
+}
+
+AtomicComparator::~AtomicComparator()
+{
+}
+
+AtomicComparator::ComparisonResult
+AtomicComparator::compare(const Item &,
+ const AtomicComparator::Operator,
+ const Item &) const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This function should never be called.");
+ return LessThan;
+}
+
+QString AtomicComparator::displayName(const AtomicComparator::Operator op,
+ const ComparisonType type)
+{
+ Q_ASSERT(type == AsGeneralComparison || type == AsValueComparison);
+ if(type == AsGeneralComparison)
+ {
+ switch(op)
+ {
+ case OperatorEqual:
+ return QLatin1String("=");
+ case OperatorGreaterOrEqual:
+ return QLatin1String("<=");
+ case OperatorGreaterThan:
+ return QLatin1String("<");
+ case OperatorLessOrEqual:
+ return QLatin1String(">=");
+ case OperatorLessThanNaNLeast:
+ /* Fallthrough. */
+ case OperatorLessThanNaNGreatest:
+ /* Fallthrough. */
+ case OperatorLessThan:
+ return QLatin1String(">");
+ case OperatorNotEqual:
+ return QLatin1String("!=");
+ }
+ }
+
+ switch(op)
+ {
+ case OperatorEqual:
+ return QLatin1String("eq");
+ case OperatorGreaterOrEqual:
+ return QLatin1String("ge");
+ case OperatorGreaterThan:
+ return QLatin1String("gt");
+ case OperatorLessOrEqual:
+ return QLatin1String("le");
+ case OperatorLessThanNaNLeast:
+ /* Fallthrough. */
+ case OperatorLessThanNaNGreatest:
+ /* Fallthrough. */
+ case OperatorLessThan:
+ return QLatin1String("lt");
+ case OperatorNotEqual:
+ return QLatin1String("ne");
+ }
+
+ Q_ASSERT(false);
+ return QString(); /* GCC unbarfer. */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qatomiccomparator_p.h b/src/xmlpatterns/data/qatomiccomparator_p.h
new file mode 100644
index 0000000..304bd92
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparator_p.h
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicComparator_H
+#define Patternist_AtomicComparator_H
+
+#include <QFlags>
+
+#include "qitem_p.h"
+#include "qatomictypedispatch_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+namespace QPatternist
+{
+
+ /**
+ * @short Base class for classes responsible of comparing two atomic values.
+ *
+ * This class is also known as the AtomicParrot.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT AtomicComparator : public AtomicTypeVisitorResult
+ {
+ public:
+ AtomicComparator();
+ virtual ~AtomicComparator();
+
+ typedef QExplicitlySharedDataPointer<AtomicComparator> Ptr;
+
+ /**
+ * Identifies operators used in value comparisons.
+ *
+ * The enum values are bit-significant.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-value-comparisons">W3C XML Path
+ * Language (XPath) 2.0, 3.5.1 Value Comparisons</a>
+ */
+ enum Operator
+ {
+ /**
+ * Operator <tt>eq</tt> and <tt>=</tt>.
+ */
+ OperatorEqual = 1,
+
+ /**
+ * Operator <tt>ne</tt> and <tt>!=</tt>.
+ */
+ OperatorNotEqual = 1 << 1,
+
+ /**
+ * Operator <tt>gt</tt> and <tt>\></tt>.
+ */
+ OperatorGreaterThan = 1 << 2,
+
+ /**
+ * Operator <tt>lt</tt> and <tt>\<</tt>.
+ */
+ OperatorLessThan = 1 << 3,
+
+ /**
+ * One of the operators we use for sorting. The only difference from
+ * OperatorLessThan is that it sees NaN as ordered and smaller than
+ * other numbers.
+ */
+ OperatorLessThanNaNLeast = 1 << 4,
+
+ /**
+ * One of the operators we use for sorting. The only difference from
+ * OperatorLessThanLeast is that it sees NaN as ordered and larger than
+ * other numbers.
+ */
+ OperatorLessThanNaNGreatest = 1 << 5,
+
+ /**
+ * Operator <tt>ge</tt> and <tt>\>=</tt>.
+ */
+ OperatorGreaterOrEqual = OperatorEqual | OperatorGreaterThan,
+
+ /**
+ * Operator <tt>le</tt> and <tt>\<=</tt>.
+ */
+ OperatorLessOrEqual = OperatorEqual | OperatorLessThan
+ };
+
+ typedef QFlags<Operator> Operators;
+
+ /**
+ * Signifies the result of a value comparison. This is used for value comparisons,
+ * and in the future likely also for sorting.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-value-comparisons">W3C XML Path
+ * Language (XPath) 2.0, 3.5.1 Value Comparisons</a>
+ */
+ enum ComparisonResult
+ {
+ LessThan = 1,
+ Equal = 2,
+ GreaterThan = 4,
+ Incomparable = 8
+ };
+
+ /**
+ * Compares @p op1 and @p op2 and determines the relationship between the two. This
+ * is used for sorting and comparisons. The implementation performs an assert crash,
+ * and must therefore be re-implemented if comparing the relevant values should be
+ * possible.
+ *
+ * @param op1 the first operand
+ * @param op the operator. How a comparison is carried out shouldn't depend on what the
+ * operator is, but in some cases it is of interest.
+ * @param op2 the second operand
+ */
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+
+ /**
+ * Determines whether @p op1 and @p op2 are equal. It is the same as calling compare()
+ * and checking whether the return value is Equal, but since comparison testing is such
+ * a common operation, this specialized function exists.
+ *
+ * @returns true if @p op1 and @p op2 are equal.
+ *
+ * @param op1 the first operand
+ * @param op2 the second operand
+ */
+ virtual bool equals(const Item &op1,
+ const Item &op2) const = 0;
+
+ /**
+ * Identifies the kind of comparison.
+ */
+ enum ComparisonType
+ {
+ /**
+ * Identifies a general comparison; operator @c =, @c >, @c <=, and so on.
+ */
+ AsGeneralComparison = 1,
+
+ /**
+ * Identifies a value comparison; operator @c eq, @c lt, @c le, and so on.
+ */
+ AsValueComparison
+ };
+
+ /**
+ * Utility function for getting the lexical representation for
+ * the comparison operator @p op. Depending on the @p type argument,
+ * the string returned is either a general comparison or a value comparison
+ * operator.
+ *
+ * @param op the operator which the display name should be determined for.
+ * @param type signifies whether the returned display name should be for
+ * a value comparison or a general comparison. For example, if @p op is
+ * OperatorEqual and @p type is AsValueComparision, "eq" is returned.
+ */
+ static QString displayName(const AtomicComparator::Operator op,
+ const ComparisonType type);
+
+ };
+ Q_DECLARE_OPERATORS_FOR_FLAGS(AtomicComparator::Operators)
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomiccomparators.cpp b/src/xmlpatterns/data/qatomiccomparators.cpp
new file mode 100644
index 0000000..38d7092
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparators.cpp
@@ -0,0 +1,386 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractduration_p.h"
+#include "qabstractdatetime_p.h"
+#include "qbase64binary_p.h"
+#include "qboolean_p.h"
+#include "qdynamiccontext_p.h"
+#include "qqnamevalue_p.h"
+
+#include "qatomiccomparators_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/* -------------------------------------------------- */
+AtomicComparator::ComparisonResult
+StringComparator::compare(const Item &o1,
+ const AtomicComparator::Operator,
+ const Item &o2) const
+{
+ const int result = QString::compare(o1.stringValue(), o2.stringValue());
+
+ if(result > 0)
+ return GreaterThan;
+ else if(result < 0)
+ return LessThan;
+ else
+ {
+ Q_ASSERT(result == 0);
+ return Equal;
+ }
+}
+
+bool StringComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ return o1.stringValue() == o2.stringValue();
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+AtomicComparator::ComparisonResult
+CaseInsensitiveStringComparator::compare(const Item &o1,
+ const AtomicComparator::Operator,
+ const Item &o2) const
+{
+ const QString i1(o1.stringValue().toLower());
+ const QString i2(o2.stringValue().toLower());
+ const int result = QString::compare(i1, i2);
+
+ if(result > 0)
+ return GreaterThan;
+ else if(result < 0)
+ return LessThan;
+ else
+ {
+ Q_ASSERT(result == 0);
+ return Equal;
+ }
+}
+
+bool CaseInsensitiveStringComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ const QString s1(o1.stringValue());
+ const QString s2(o2.stringValue());
+
+ return s1.length() == s2.length() &&
+ s1.startsWith(s2, Qt::CaseInsensitive);
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+bool BinaryDataComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ return o1.as<Base64Binary>()->asByteArray() ==
+ o2.as<Base64Binary>()->asByteArray();
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+AtomicComparator::ComparisonResult
+BooleanComparator::compare(const Item &o1,
+ const AtomicComparator::Operator,
+ const Item &o2) const
+{
+ /* We know Boolean::evaluateEBV doesn't use the DynamicContext. */
+ const bool v1 = o1.as<AtomicValue>()->evaluateEBV(QExplicitlySharedDataPointer<DynamicContext>());
+ const bool v2 = o2.as<AtomicValue>()->evaluateEBV(QExplicitlySharedDataPointer<DynamicContext>());
+
+ if(v1 == v2)
+ return Equal;
+ else if(v1 == false)
+ {
+ Q_ASSERT(v2 == true);
+ return LessThan;
+ }
+ else
+ {
+ Q_ASSERT(v1 == true && v2 == false);
+ return GreaterThan;
+ }
+}
+
+bool BooleanComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ /* Boolean is an atomic class. */
+ return o1.as<AtomicValue>() == o2.as<AtomicValue>();
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+AtomicComparator::ComparisonResult
+AbstractFloatComparator::compare(const Item &o1,
+ const AtomicComparator::Operator op,
+ const Item &o2) const
+{
+ const xsDouble v1 = o1.as<Numeric>()->toDouble();
+ const xsDouble v2 = o2.as<Numeric>()->toDouble();
+
+ if(Double::isEqual(v1, v2))
+ return Equal;
+ else if(v1 < v2)
+ return LessThan;
+ else if(v1 > v2)
+ return GreaterThan;
+ else
+ {
+ /* We have NaN values. Make sure we don't return a result which would
+ * signify success for the operator in question. */
+ if((op & OperatorGreaterThan) == OperatorGreaterThan)
+ return LessThan;
+ else
+ {
+ Q_ASSERT((op & OperatorLessThan) == OperatorLessThan);
+ return GreaterThan;
+ }
+ }
+}
+
+bool AbstractFloatComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ return Double::isEqual(o1.as<Numeric>()->toDouble(), o2.as<Numeric>()->toDouble());
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+AtomicComparator::ComparisonResult
+DecimalComparator::compare(const Item &o1,
+ const AtomicComparator::Operator,
+ const Item &o2) const
+{
+ const xsDecimal v1 = o1.as<Numeric>()->toDecimal();
+ const xsDecimal v2 = o2.as<Numeric>()->toDecimal();
+
+ if(Double::isEqual(v1, v2))
+ return Equal;
+ else if(v1 < v2)
+ return LessThan;
+ else
+ return GreaterThan;
+}
+
+bool DecimalComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ return Double::isEqual(o1.as<Numeric>()->toDecimal(), o2.as<Numeric>()->toDecimal());
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+AtomicComparator::ComparisonResult
+IntegerComparator::compare(const Item &o1,
+ const AtomicComparator::Operator,
+ const Item &o2) const
+{
+ const Numeric *const num1 = o1.as<Numeric>();
+ const Numeric *const num2 = o1.as<Numeric>();
+
+ /**
+ * Consider:
+ * xs:unsignedLong("100") > xs:unsignedLong("18446744073709551615")
+ *
+ * If we perform math on the values as if they were xsInteger, the right
+ * operand overflows, wraps around, and the expression evaluates to false.
+ * Hence we have this code to deal with it.
+ *
+ * This is runtime code, it would have been better if we had separate
+ * AtomicComparator classes for signed and unsigned values, but the changes
+ * required to the lookup code are extensive.
+ */
+ if(num1->isSigned() || num2->isSigned())
+ {
+ const xsInteger v1 = o1.as<Numeric>()->toInteger();
+ const xsInteger v2 = o2.as<Numeric>()->toInteger();
+
+ if(v1 == v2)
+ return Equal;
+ else if(v1 < v2)
+ return LessThan;
+ else
+ return GreaterThan;
+ }
+ else
+ {
+ const qulonglong v1 = o1.as<Numeric>()->toUnsignedInteger();
+ const qulonglong v2 = o2.as<Numeric>()->toUnsignedInteger();
+
+ if(v1 == v2)
+ return Equal;
+ else if(v1 < v2)
+ return LessThan;
+ else
+ return GreaterThan;
+ }
+}
+
+bool IntegerComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ return o1.as<Numeric>()->toInteger() == o2.as<Numeric>()->toInteger();
+}
+
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+bool QNameComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ return o1.as<QNameValue>()->m_qName ==
+ o2.as<QNameValue>()->m_qName;
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+bool AbstractDateTimeComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ const QDateTime dt1(o1.as<AbstractDateTime>()->toDateTime());
+ const QDateTime dt2(o2.as<AbstractDateTime>()->toDateTime());
+
+ /*
+ pDebug() << "COMPARING:"
+ << o1->as<AbstractDateTime>()->toDateTime().toString()
+ << o2->as<AbstractDateTime>()->toDateTime().toString();
+ pDebug() << "DATE ONLY:"
+ << o1->as<AbstractDateTime>()->toDateTime().isDateOnly()
+ << o2->as<AbstractDateTime>()->toDateTime().isDateOnly();
+ */
+ return dt1 == dt2 &&
+ dt1.timeSpec() == dt2.timeSpec();
+}
+
+AtomicComparator::ComparisonResult
+AbstractDateTimeComparator::compare(const Item &operand1,
+ const AtomicComparator::Operator,
+ const Item &operand2) const
+{
+ const QDateTime &dt1 = operand1.as<AbstractDateTime>()->toDateTime();
+ const QDateTime &dt2 = operand2.as<AbstractDateTime>()->toDateTime();
+
+ if(dt1 == dt2)
+ return Equal;
+ else if(dt1 < dt2)
+ return LessThan;
+ else
+ return GreaterThan;
+}
+/* -------------------------------------------------- */
+
+/* -------------------------------------------------- */
+bool AbstractDurationComparator::equals(const Item &o1,
+ const Item &o2) const
+{
+ /* We use AbstractDuration::operator==() */
+ return *o1.as<AbstractDuration>() ==
+ *o2.as<AbstractDuration>();
+}
+
+QDateTime AbstractDurationComparator::addDurationToDateTime(const QDateTime &dateTime,
+ const AbstractDuration *const duration)
+{
+ QDateTime result(dateTime);
+ qint64 seconds = 0;
+
+ const qint8 signMultiplier = (duration->isPositive() ? 1 : -1);
+
+ result = result.addYears(signMultiplier * duration->years());
+ result = result.addMonths(signMultiplier * duration->months());
+ result = result.addDays(signMultiplier * duration->days());
+
+ seconds = 60 * 60 * duration->hours();
+ seconds += 60 * duration->minutes();
+ seconds += duration->seconds();
+
+ result = result.addSecs(signMultiplier * seconds);
+ result = result.addMSecs(signMultiplier * duration->mseconds());
+
+ return result;
+}
+
+AtomicComparator::ComparisonResult
+AbstractDurationComparator::compare(const Item &o1,
+ const AtomicComparator::Operator,
+ const Item &o2) const
+{
+ const AbstractDuration *const duration = o1.as<AbstractDuration>();
+ const AbstractDuration *const otherDuration = o2.as<AbstractDuration>();
+
+ const QDateTime dateTime1(QDate(1696, 9, 1), QTime(0, 0, 0), Qt::UTC);
+ const QDateTime dateTime2(QDate(1697, 2, 1), QTime(0, 0, 0), Qt::UTC);
+ const QDateTime dateTime3(QDate(1903, 3, 1), QTime(0, 0, 0), Qt::UTC);
+ const QDateTime dateTime4(QDate(1903, 7, 1), QTime(0, 0, 0), Qt::UTC);
+
+ const QDateTime durationDateTime1 = addDurationToDateTime(dateTime1, duration);
+ const QDateTime durationDateTime2 = addDurationToDateTime(dateTime2, duration);
+ const QDateTime durationDateTime3 = addDurationToDateTime(dateTime3, duration);
+ const QDateTime durationDateTime4 = addDurationToDateTime(dateTime4, duration);
+
+ const QDateTime otherDurationDateTime1 = addDurationToDateTime(dateTime1, otherDuration);
+ const QDateTime otherDurationDateTime2 = addDurationToDateTime(dateTime2, otherDuration);
+ const QDateTime otherDurationDateTime3 = addDurationToDateTime(dateTime3, otherDuration);
+ const QDateTime otherDurationDateTime4 = addDurationToDateTime(dateTime4, otherDuration);
+
+ if (durationDateTime1 > otherDurationDateTime1 &&
+ durationDateTime2 > otherDurationDateTime2 &&
+ durationDateTime3 > otherDurationDateTime3 &&
+ durationDateTime4 > otherDurationDateTime4) {
+ return GreaterThan;
+ } else if (durationDateTime1 < otherDurationDateTime1 &&
+ durationDateTime2 < otherDurationDateTime2 &&
+ durationDateTime3 < otherDurationDateTime3 &&
+ durationDateTime4 < otherDurationDateTime4) {
+ return LessThan;
+ } else if (*duration == *otherDuration) {
+ return Equal;
+ } else {
+ return Incomparable;
+ }
+}
+
+/* -------------------------------------------------- */
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qatomiccomparators_p.h b/src/xmlpatterns/data/qatomiccomparators_p.h
new file mode 100644
index 0000000..614916f
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparators_p.h
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicComparators_H
+#define Patternist_AtomicComparators_H
+
+#include "qabstractfloat_p.h"
+#include "qatomiccomparator_p.h"
+#include "qprimitives_p.h"
+
+/**
+ * @file
+ * @short Contains all the classes implementing comparisons between atomic values.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Performs case @em sensitive string comparison
+ * between @c xs:anyUri, @c xs:string, and @c xs:untypedAtomic.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringComparator : public AtomicComparator
+ {
+ public:
+ /**
+ * Compares two strings, and returns the appropriate AtomicComparator::ComparisonResult enum. This
+ * is a bit simplified version of string comparison as defined in the XPath specifications,
+ * since this does not take any string collations into account(which an implementation neither
+ * is required to do).
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#string-compare">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators, 7.3 ValueComparison::Equality and Comparison of Strings</a>
+ */
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+
+ /**
+ * Compares two strings, and returns @c true if they are considered equal as per
+ * an ordinary string comparison. In other words, this is an implementation with
+ * the Unicode code point collation.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#string-compare">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators, 7.3 ValueComparison::Equality and Comparison of Strings</a>
+ */
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Performs case @em insensitive string comparison
+ * between @c xs:anyUri, @c xs:string, and @c xs:untypedAtomic.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class CaseInsensitiveStringComparator : public AtomicComparator
+ {
+ public:
+ /**
+ * Converts both string values to upper case and afterwards compare them.
+ */
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+
+ /**
+ * Converts both string values case insensitively.
+ */
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares @c xs:base64Binary and @c xs:hexBinary values.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BinaryDataComparator : public AtomicComparator
+ {
+ public:
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares @c xs:boolean values.
+ *
+ * This is done via the object's Boolean::evaluteEBV() function.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BooleanComparator : public AtomicComparator
+ {
+ public:
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares @c xs:double values.
+ *
+ * @todo Add docs about numeric promotion
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractFloatComparator : public AtomicComparator
+ {
+ public:
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares @c xs:double values for the purpose of sorting.
+ *
+ * @todo Add docs about numeric promotion
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<const AtomicComparator::Operator t_op>
+ class AbstractFloatSortComparator : public AbstractFloatComparator
+ {
+ public:
+ virtual ComparisonResult compare(const Item &o1,
+ const AtomicComparator::Operator op,
+ const Item &o2) const
+ {
+ Q_ASSERT_X(t_op == OperatorLessThanNaNLeast || t_op == OperatorLessThanNaNGreatest, Q_FUNC_INFO,
+ "Can only be instantiated with those two.");
+ Q_ASSERT(op == t_op);
+ Q_UNUSED(op); /* Needed when building in release mode. */
+
+ const xsDouble v1 = o1.template as<Numeric>()->toDouble();
+ const xsDouble v2 = o2.template as<Numeric>()->toDouble();
+
+ if(qIsNaN(v1) && !qIsNaN(v2))
+ return t_op == OperatorLessThanNaNLeast ? LessThan : GreaterThan;
+ if(!qIsNaN(v1) && qIsNaN(v2))
+ return t_op == OperatorLessThanNaNLeast ? GreaterThan : LessThan;
+
+ if(Double::isEqual(v1, v2))
+ return Equal;
+ else if(v1 < v2)
+ return LessThan;
+ else
+ return GreaterThan;
+ }
+
+ };
+
+ /**
+ * @short Compares @c xs:decimal values.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DecimalComparator : public AtomicComparator
+ {
+ public:
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares @c xs:integer values.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class IntegerComparator : public AtomicComparator
+ {
+ public:
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares @c xs:QName values.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class QNameComparator : public AtomicComparator
+ {
+ public:
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares sub-classes of AbstractDateTime.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeComparator : public AtomicComparator
+ {
+ public:
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+ };
+
+ /**
+ * @short Compares sub-classes of AbstractDuration.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDurationComparator : public AtomicComparator
+ {
+ public:
+ virtual ComparisonResult compare(const Item &op1,
+ const AtomicComparator::Operator op,
+ const Item &op2) const;
+ virtual bool equals(const Item &op1,
+ const Item &op2) const;
+
+ private:
+ static inline QDateTime addDurationToDateTime(const QDateTime &dateTime,
+ const AbstractDuration *const duration);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomicmathematician.cpp b/src/xmlpatterns/data/qatomicmathematician.cpp
new file mode 100644
index 0000000..ddd27a9
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematician.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicmathematician_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicMathematician::~AtomicMathematician()
+{
+}
+
+QString AtomicMathematician::displayName(const AtomicMathematician::Operator op)
+{
+ switch(op)
+ {
+ case AtomicMathematician::Div:
+ return QLatin1String("div");
+ case AtomicMathematician::IDiv:
+ return QLatin1String("idiv");
+ case AtomicMathematician::Substract:
+ return QLatin1String("-");
+ case AtomicMathematician::Mod:
+ return QLatin1String("mod");
+ case AtomicMathematician::Multiply:
+ return QLatin1String("*");
+ case AtomicMathematician::Add:
+ return QLatin1String("+");
+ }
+
+ return QString(); /* Silence GCC warning. */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qatomicmathematician_p.h b/src/xmlpatterns/data/qatomicmathematician_p.h
new file mode 100644
index 0000000..a61e1b0
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematician_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicMathematician_H
+#define Patternist_AtomicMathematician_H
+
+#include <QFlags>
+
+#include "qdynamiccontext_p.h"
+#include "qitem_p.h"
+#include "qatomictypedispatch_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for classes that performs arithmetic operations between atomic values.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT AtomicMathematician : public AtomicTypeVisitorResult
+ {
+ public:
+ virtual ~AtomicMathematician();
+
+ typedef QExplicitlySharedDataPointer<AtomicMathematician> Ptr;
+
+ enum Operator
+ {
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-divide">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.2.4 op:numeric-divide</a>
+ */
+ Div = 1,
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-integer-divide">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.2.5 op:numeric-integer-divide</a>
+ */
+ IDiv = 2,
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-subtract">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.2.2 op:numeric-subtract</a>
+ */
+ Substract = 4,
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-mod">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.2.6 op:numeric-mod</a>
+ */
+ Mod = 8,
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-multiply">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.2.3 op:numeric-multiply</a>
+ */
+ Multiply = 16,
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-add">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.2.1 op:numeric-add</a>
+ */
+ Add = 32
+ };
+
+ typedef QFlags<Operator> Operators;
+
+ virtual Item calculate(const Item &operand1,
+ const Operator op,
+ const Item &operand2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const = 0;
+
+ static QString displayName(const AtomicMathematician::Operator op);
+
+ };
+ Q_DECLARE_OPERATORS_FOR_FLAGS(AtomicMathematician::Operators)
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomicmathematicians.cpp b/src/xmlpatterns/data/qatomicmathematicians.cpp
new file mode 100644
index 0000000..3c6ce40
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematicians.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <math.h>
+
+#include <qnumeric.h>
+
+#include "qabstractdatetime_p.h"
+#include "qabstractduration_p.h"
+#include "qabstractfloat_p.h"
+#include "qdaytimeduration_p.h"
+#include "qdecimal_p.h"
+#include "qinteger_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qatomicmathematicians_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/* The translation strings is place here once, in order to reduce work for translators,
+ * and provide consistency. */
+
+static inline QString idivZeroInvalid()
+{
+ return QtXmlPatterns::tr("Integer division (%1) by zero (%2) is undefined.")
+ .arg(formatKeyword("idiv"))
+ .arg(formatData("0"));
+}
+
+static inline QString divZeroInvalid()
+{
+ return QtXmlPatterns::tr("Division (%1) by zero (%2) is undefined.")
+ .arg(formatKeyword("div"))
+ .arg(formatData("0"));
+}
+
+static inline QString modZeroInvalid()
+{
+ return QtXmlPatterns::tr("Modulus division (%1) by zero (%2) is undefined.")
+ .arg(formatKeyword("mod"))
+ .arg(formatData("0"));
+}
+
+Item DecimalMathematician::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ switch(op)
+ {
+ case Div:
+ {
+ if(o2.as<Numeric>()->toInteger() == 0)
+ {
+ context->error(divZeroInvalid(), ReportContext::FOAR0001, this);
+ return Item(); /* Silences source code analyzer warning. */
+ }
+ else
+ return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() / o2.as<Numeric>()->toDecimal()));
+ }
+ case IDiv:
+ {
+ if(o2.as<Numeric>()->toInteger() == 0)
+ {
+ context->error(idivZeroInvalid(), ReportContext::FOAR0001, this);
+ return Item(); /* Silences source code analyzer warning. */
+ }
+ else
+ return Integer::fromValue(static_cast<xsInteger>(o1.as<Numeric>()->toDecimal() /
+ o2.as<Numeric>()->toDecimal()));
+ }
+ case Substract:
+ return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() - o2.as<Numeric>()->toDecimal()));
+ case Mod:
+ {
+ if(o2.as<Numeric>()->toInteger() == 0)
+ {
+ context->error(modZeroInvalid(), ReportContext::FOAR0001, this);
+ return Item(); /* Silences source code analyzer warning. */
+ }
+ else
+ return toItem(Decimal::fromValue(::fmod(o1.as<Numeric>()->toDecimal(), o2.as<Numeric>()->toDecimal())));
+ }
+ case Multiply:
+ return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() * o2.as<Numeric>()->toDecimal()));
+ case Add:
+ return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() + o2.as<Numeric>()->toDecimal()));
+ }
+
+ Q_ASSERT(false);
+ return Item(); /* GCC unbarfer. */
+}
+
+Item IntegerMathematician::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ switch(op)
+ {
+ case Div:
+ if(o2.as<Numeric>()->toInteger() == 0)
+ {
+ context->error(divZeroInvalid(), ReportContext::FOAR0001, this);
+ return Item(); /* Silences source code analyzer warning. */
+ }
+ else /* C++ automatically performs truncation of long integer(xsInteger). */
+ return toItem(Decimal::fromValue(o1.as<Numeric>()->toDecimal() / o2.as<Numeric>()->toDecimal()));
+ case IDiv:
+ {
+ if(o2.as<Numeric>()->toInteger() == 0)
+ {
+ context->error(idivZeroInvalid(), ReportContext::FOAR0001, this);
+ return Item(); /* Silences source code analyzer warning. */
+ }
+ else /* C++ automatically performs truncation of long integer(xsInteger). */
+ return Integer::fromValue(o1.as<Numeric>()->toInteger() / o2.as<Numeric>()->toInteger());
+ }
+ case Substract:
+ return Integer::fromValue(o1.as<Numeric>()->toInteger() - o2.as<Numeric>()->toInteger());
+ case Mod:
+ {
+ const xsInteger divisor = o2.as<Numeric>()->toInteger();
+
+ if(divisor == 0)
+ {
+ context->error(modZeroInvalid(), ReportContext::FOAR0001, this);
+ return Item(); /* Silences source code analyzer warning. */
+ }
+ else
+ return Integer::fromValue(o1.as<Numeric>()->toInteger() % divisor);
+ }
+ case Multiply:
+ return Integer::fromValue(o1.as<Numeric>()->toInteger() * o2.as<Numeric>()->toInteger());
+ case Add:
+ return Integer::fromValue(o1.as<Numeric>()->toInteger() + o2.as<Numeric>()->toInteger());
+ }
+
+ Q_ASSERT(false);
+ return Item(); /* GCC unbarfer. */
+}
+
+Item DurationNumericMathematician::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ Q_ASSERT(op == Div || op == Multiply);
+
+ const AbstractDuration::Ptr duration(o1.as<AbstractDuration>());
+ const xsDouble dbl = o2.as<Numeric>()->toDouble();
+
+ switch(op)
+ {
+ case Div:
+ {
+ if(qIsInf(dbl))
+ return duration->fromValue(0);
+ else if(qIsNaN(dbl))
+ {
+ context->error(QtXmlPatterns::tr(
+ "Dividing a value of type %1 by %2 (not-a-number) "
+ "is not allowed.")
+ .arg(formatType(context->namePool(),
+ duration->type()))
+ .arg(formatData("NaN")),
+ ReportContext::FOCA0005,
+ this);
+ return Item();
+ }
+ else if(Double::isEqual(dbl, 0))
+ {
+ context->error(QtXmlPatterns::tr(
+ "Dividing a value of type %1 by %2 or %3 (plus or "
+ "minus zero) is not allowed.")
+ .arg(formatType(context->namePool(),
+ duration->type()))
+ .arg(formatData("-0"))
+ .arg(formatData("0")),
+ ReportContext::FODT0002,
+ this);
+ return Item();
+ }
+
+ return duration->fromValue(static_cast<AbstractDuration::Value>(duration->value() / dbl));
+ }
+ case Multiply:
+ {
+ if(Double::isEqual(dbl, 0))
+ return duration->fromValue(0);
+ else if(qIsNaN(dbl))
+ {
+ context->error(QtXmlPatterns::tr(
+ "Dividing a value of type %1 by %2 (not-a-number) "
+ "is not allowed.")
+ .arg(formatType(context->namePool(),
+ duration->type()))
+ .arg(formatData("NaN")),
+ ReportContext::FOCA0005,
+ this);
+ return Item();
+ }
+ else if(qIsInf(dbl))
+ {
+ context->error(QtXmlPatterns::tr(
+ "Multiplication of a value of type %1 by %2 or %3 "
+ "(plus or minus infinity) is not allowed.")
+ .arg(formatType(context->namePool(),
+ duration->type()))
+ .arg(formatData("-INF"))
+ .arg(formatData("INF")),
+ ReportContext::FODT0002,
+ this);
+ return Item();
+ }
+
+ return duration->fromValue(static_cast<AbstractDuration::Value>(duration->value() * dbl));
+ }
+ default:
+ {
+ Q_ASSERT(false);
+ return Item(); /* Silence warning. */
+ }
+ }
+}
+
+Item DurationDurationMathematician::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ const AbstractDuration::Ptr duration(o1.as<AbstractDuration>());
+ const AbstractDuration::Value op2 = o2.as<AbstractDuration>()->value();
+
+ switch(op)
+ {
+ case Div:
+ return toItem(Decimal::fromValue(static_cast<xsDecimal>(duration->value()) / op2));
+ case Substract:
+ return duration->fromValue(duration->value() - op2);
+ case Add:
+ return duration->fromValue(duration->value() + op2);
+ default:
+ {
+ Q_ASSERT(false);
+ return Item(); /* Silence warning. */
+ }
+ }
+}
+
+OperandSwitcherMathematician::
+OperandSwitcherMathematician(const AtomicMathematician::Ptr &mathematician) : m_mather(mathematician)
+{
+ Q_ASSERT(mathematician);
+}
+
+Item OperandSwitcherMathematician::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ return m_mather->calculate(o2, op, o1, context);
+}
+
+
+Item DateTimeDurationMathematician::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ Q_ASSERT(op == Substract || op == Add);
+
+ const AbstractDateTime::Ptr adt(o1.as<AbstractDateTime>());
+ const AbstractDuration::Ptr dur(o2.as<AbstractDuration>());
+ QDateTime dt(adt->toDateTime());
+ //pDebug() << "DateTimeDurationMathematician::calculate():" << dt.toString();
+ //dt.setDateOnly(false);
+ const qint8 sign = (op == Add ? 1 : -1) * (dur->isPositive() ? 1 : -1);
+
+ // TODO milli seconds
+ dt = dt.addSecs(sign * (dur->seconds() + dur->minutes() * 60 + dur->hours() * 60 * 60));
+ dt = dt.addDays(sign * dur->days());
+ dt = dt.addMonths(sign * dur->months());
+ dt = dt.addYears(sign * dur->years());
+
+ QString msg;
+
+ if(AbstractDateTime::isRangeValid(dt.date(), msg))
+ return adt->fromValue(dt);
+ else
+ {
+ context->error(msg, ReportContext::FODT0001,
+ this);
+ return Item();
+ }
+}
+
+Item AbstractDateTimeMathematician::calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ Q_ASSERT(op == Substract || op == Add);
+ QDateTime dt1(o1.as<AbstractDateTime>()->toDateTime());
+ QDateTime dt2(o2.as<AbstractDateTime>()->toDateTime());
+
+ const int diff = op == Add ? dt1.secsTo(dt2) : dt2.secsTo(dt1);
+
+ return toItem(DayTimeDuration::fromSeconds(diff));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qatomicmathematicians_p.h b/src/xmlpatterns/data/qatomicmathematicians_p.h
new file mode 100644
index 0000000..607f303
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematicians_p.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicMathematicians_H
+#define Patternist_AtomicMathematicians_H
+
+#include "qatomicmathematician_p.h"
+#include "qsourcelocationreflection_p.h"
+
+/**
+ * @file
+ * @short Contains classes performing arithemetic operations between atomic values, such as
+ * subtracting two dates.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DecimalMathematician : public AtomicMathematician
+ , public DelegatingSourceLocationReflection
+ {
+ public:
+ inline DecimalMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r)
+ {
+ }
+
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Performs arithmetics between Integer values.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class IntegerMathematician : public AtomicMathematician
+ , public DelegatingSourceLocationReflection
+ {
+ public:
+ inline IntegerMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r)
+ {
+ }
+
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Performs division or multiplication between either DayTimeDuration or YearMonthDuration
+ * and Double values.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DurationNumericMathematician : public AtomicMathematician
+ , public DelegatingSourceLocationReflection
+ {
+ public:
+ inline DurationNumericMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r)
+ {
+ }
+
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Performs division between DayTimeDuration and DayTimeDuration, or
+ * YearMonthDuration and YearMonthDuration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DurationDurationDivisor : public AtomicMathematician
+ {
+ public:
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Performs arithmetics between DayTimeDuration and DayTimeDuration, or
+ * YearMonthDuration and YearMonthDuration.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DurationDurationMathematician : public AtomicMathematician
+ {
+ public:
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Delegates an AtomicMathematician and switches its operands.
+ *
+ * Switches the operands of the call to a call to the calculate()
+ * on an AtomicMathematician such that the left operand becomes the right, and
+ * vice versa.
+ *
+ * Its constructor takes an AtomicMathematician instance which this OperandSwitcherMathematician
+ * should act as as a middle-man for, having the role of switching the two operands. Thus,
+ * OperandSwitcherMathematician can be described as a proxy or delegator class.
+ *
+ * This class is used for implementing operator combinations such as
+ * <tt>numeric * xs:yearMonthDuration</tt> and
+ * <tt>xs:yearMonthDuration * numeric</tt>.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class OperandSwitcherMathematician : public AtomicMathematician
+ {
+ public:
+ /**
+ * Creates an OperandSwitcherMathematician.
+ *
+ * @param mathematician the AtomicMathematician this OperandSwitcherMathematician
+ * should switch the operands for. Must be a non @c null, valid pointer.
+ */
+ OperandSwitcherMathematician(const AtomicMathematician::Ptr &mathematician);
+
+ /**
+ * Switch @p o1 and @p o2, and returns the value from the AtomicMathematician
+ * this OperandSwitcherMathematician represents.
+ */
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ private:
+ const AtomicMathematician::Ptr m_mather;
+ };
+
+ /**
+ * @short Performs arithmetics between an AbstractDateTime value and
+ * an AbstractDuration value.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DateTimeDurationMathematician : public AtomicMathematician
+ , public DelegatingSourceLocationReflection
+ {
+ public:
+
+ inline DateTimeDurationMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r)
+ {
+ }
+
+ /**
+ * @p o1 is an AbstractDateTime and @p o2 is an AbstractDuration.
+ *
+ */
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+
+ /**
+ * @short Performs arithmetics between two AbstractDateTime values.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractDateTimeMathematician : public AtomicMathematician
+ {
+ public:
+ virtual Item calculate(const Item &o1,
+ const Operator op,
+ const Item &o2,
+ const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomicstring.cpp b/src/xmlpatterns/data/qatomicstring.cpp
new file mode 100644
index 0000000..134607f
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicstring.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qatomicstring_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicString::AtomicString(const QString &s) : m_value(s)
+{
+}
+
+AtomicString::Ptr AtomicString::fromValue(const QString &value)
+{
+ return AtomicString::Ptr(new AtomicString(value));
+}
+
+bool AtomicString::evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return m_value.length() > 0;
+}
+
+QString AtomicString::stringValue() const
+{
+ return m_value;
+}
+
+ItemType::Ptr AtomicString::type() const
+{
+ return BuiltinTypes::xsString;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qatomicstring_p.h b/src/xmlpatterns/data/qatomicstring_p.h
new file mode 100644
index 0000000..278b822
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicstring_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_String_H
+#define Patternist_String_H
+
+#include <QUrl>
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:string type.
+ *
+ *
+ * This class was originally called String, and correspondingly the header
+ * file was called String.h. However, this broke building on OS X, which
+ * looks up file names case insensitively, and therefore found string.h.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo Documentation is missing/incomplete
+ */
+ class Q_AUTOTEST_EXPORT AtomicString : public AtomicValue
+ {
+ public:
+ friend class CommonValues;
+
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance representing @p value.
+ *
+ * @note This function does not remove the string literal escaping allowed in XPath 2.0
+ */
+ static AtomicString::Ptr fromValue(const QString &value);
+
+ static inline AtomicString::Ptr fromValue(const QUrl &value)
+ {
+ return fromValue(value.toString());
+ }
+
+ /**
+ * Get the Effective %Boolean Value of this string. A zero-length
+ * string has an effective boolean value of @c false, in all other cases @c true.
+ *
+ * @returns @c false if the contained string has a zero-length, otherwise @c true.
+ */
+ virtual bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const;
+
+ /**
+ * The string value of a AtomicString instance is the value space.
+ */
+ virtual QString stringValue() const;
+
+ virtual ItemType::Ptr type() const;
+
+ protected:
+ friend class StringComparator;
+ friend class CompareFN;
+ AtomicString(const QString &value);
+ const QString m_value;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp
new file mode 100644
index 0000000..a15a6b4
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicvalue.cpp
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QVariant>
+
+#include "qabstractdatetime_p.h"
+#include "qabstractfloat_p.h"
+#include "qatomicstring_p.h"
+#include "qatomictype_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qdate_p.h"
+#include "qschemadatetime_p.h"
+#include "qderivedinteger_p.h"
+#include "qdynamiccontext_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qhexbinary_p.h"
+#include "qinteger_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+#include "qschematime_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @file
+ * @short Contains the implementation for AtomicValue. The definition is in qitem_p.h.
+ */
+
+using namespace QPatternist;
+
+AtomicValue::~AtomicValue()
+{
+}
+
+bool AtomicValue::evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &context) const
+{
+ context->error(QtXmlPatterns::tr("A value of type %1 cannot have an "
+ "Effective Boolean Value.")
+ .arg(formatType(context->namePool(), type())),
+ ReportContext::FORG0006,
+ QSourceLocation());
+ return false; /* Silence GCC warning. */
+}
+
+bool AtomicValue::hasError() const
+{
+ return false;
+}
+
+QVariant AtomicValue::toQt(const AtomicValue *const value)
+{
+ Q_ASSERT_X(value, Q_FUNC_INFO,
+ "Internal error, a null pointer cannot be passed.");
+
+ const ItemType::Ptr t(value->type());
+
+ if(BuiltinTypes::xsString->xdtTypeMatches(t)
+ || BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t)
+ || BuiltinTypes::xsAnyURI->xdtTypeMatches(t))
+ return value->stringValue();
+ /* Note, this occurs before the xsInteger test, since xs:unsignedLong
+ * is a subtype of it. */
+ else if(*BuiltinTypes::xsUnsignedLong == *t)
+ return QVariant(value->as<DerivedInteger<TypeUnsignedLong> >()->storedValue());
+ else if(BuiltinTypes::xsInteger->xdtTypeMatches(t))
+ return QVariant(value->as<Numeric>()->toInteger());
+ else if(BuiltinTypes::xsFloat->xdtTypeMatches(t)
+ || BuiltinTypes::xsDouble->xdtTypeMatches(t)
+ || BuiltinTypes::xsDecimal->xdtTypeMatches(t))
+ return QVariant(value->as<Numeric>()->toDouble());
+ /* We currently does not support xs:time. */
+ else if(BuiltinTypes::xsDateTime->xdtTypeMatches(t))
+ return QVariant(value->as<AbstractDateTime>()->toDateTime());
+ else if(BuiltinTypes::xsDate->xdtTypeMatches(t))
+ return QVariant(value->as<AbstractDateTime>()->toDateTime().toUTC().date());
+ else if(BuiltinTypes::xsBoolean->xdtTypeMatches(t))
+ return QVariant(value->as<Boolean>()->value());
+ else if(BuiltinTypes::xsBase64Binary->xdtTypeMatches(t)
+ || BuiltinTypes::xsHexBinary->xdtTypeMatches(t))
+ return QVariant(value->as<Base64Binary>()->asByteArray());
+ else if(BuiltinTypes::xsQName->xdtTypeMatches(t))
+ return QVariant::fromValue(value->as<QNameValue>()->qName());
+ else
+ {
+ /* A type we don't support in Qt. Includes xs:time currently. */
+ return QVariant();
+ }
+}
+
+Item AtomicValue::toXDM(const QVariant &value)
+{
+ Q_ASSERT_X(value.isValid(), Q_FUNC_INFO,
+ "QVariants sent to Patternist must be valid.");
+
+ switch(value.userType())
+ {
+ case QVariant::Char:
+ /* Fallthrough. A single codepoint is a string in XQuery. */
+ case QVariant::String:
+ return AtomicString::fromValue(value.toString());
+ case QVariant::Url:
+ {
+ /* QUrl doesn't follow the spec properly, so we
+ * have to let it be an xs:string. Calling QVariant::toString()
+ * on a QVariant that contains a QUrl returns, surprisingly,
+ * an empty string. */
+ return AtomicString::fromValue(value.toUrl().toString());
+ }
+ case QVariant::ByteArray:
+ return HexBinary::fromValue(value.toByteArray());
+ case QVariant::Int:
+ /* Fallthrough. */
+ case QVariant::LongLong:
+ /* Fallthrough. */
+ case QVariant::UInt:
+ return Integer::fromValue(value.toLongLong());
+ case QVariant::ULongLong:
+ return DerivedInteger<TypeUnsignedLong>::fromValueUnchecked(value.toULongLong());
+ case QVariant::Bool:
+ return Boolean::fromValue(value.toBool());
+ case QVariant::Time:
+ return SchemaTime::fromDateTime(value.toDateTime());
+ case QVariant::Date:
+ return Date::fromDateTime(QDateTime(value.toDate(), QTime(), Qt::UTC));
+ case QVariant::DateTime:
+ return DateTime::fromDateTime(value.toDateTime());
+ case QMetaType::Float:
+ return Item(Double::fromValue(value.toFloat()));
+ case QVariant::Double:
+ return Item(Double::fromValue(value.toDouble()));
+ default:
+ {
+ if (value.userType() == qMetaTypeId<float>())
+ {
+ return Item(Float::fromValue(value.value<float>()));
+ }
+ else {
+ Q_ASSERT_X(false,
+ Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1(
+ "QVariants of type %1 are not supported in "
+ "Patternist, see the documentation")
+ .arg(QLatin1String(value.typeName()))));
+ return AtomicValue::Ptr();
+ }
+ }
+ }
+}
+
+ItemType::Ptr AtomicValue::qtToXDMType(const QXmlItem &item)
+{
+ Q_ASSERT(!item.isNull());
+
+ if(item.isNull())
+ return ItemType::Ptr();
+
+ if(item.isNode())
+ return BuiltinTypes::node;
+
+ Q_ASSERT(item.isAtomicValue());
+ const QVariant v(item.toAtomicValue());
+
+ switch(int(v.type()))
+ {
+ case QVariant::Char:
+ /* Fallthrough. */
+ case QVariant::String:
+ /* Fallthrough. */
+ case QVariant::Url:
+ return BuiltinTypes::xsString;
+ case QVariant::Bool:
+ return BuiltinTypes::xsBoolean;
+ case QVariant::ByteArray:
+ return BuiltinTypes::xsBase64Binary;
+ case QVariant::Int:
+ /* Fallthrough. */
+ case QVariant::LongLong:
+ return BuiltinTypes::xsInteger;
+ case QVariant::ULongLong:
+ return BuiltinTypes::xsUnsignedLong;
+ case QVariant::Date:
+ return BuiltinTypes::xsDate;
+ case QVariant::DateTime:
+ /* Fallthrough. */
+ case QVariant::Time:
+ return BuiltinTypes::xsDateTime;
+ case QMetaType::Float:
+ return BuiltinTypes::xsFloat;
+ case QVariant::Double:
+ return BuiltinTypes::xsDouble;
+ default:
+ return ItemType::Ptr();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qbase64binary.cpp b/src/xmlpatterns/data/qbase64binary.cpp
new file mode 100644
index 0000000..42c6cb9
--- /dev/null
+++ b/src/xmlpatterns/data/qbase64binary.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QByteArray>
+#include <QtGlobal>
+
+#include "qbuiltintypes_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qbase64binary_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Base64Binary::Base64Binary(const QByteArray &val) : m_value(val)
+{
+}
+
+const char Base64Binary::Base64DecMap[128] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+ 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+void Base64Binary::base64Decode(const QByteArray &in, QByteArray &out, bool &ok)
+{
+ out.resize(0);
+
+ if(in.isEmpty())
+ {
+ ok = false;
+ return;
+ }
+
+ ok = true;
+ int len = in.size(), tail = len;
+ const char *const data = in.data();
+ unsigned int eqCount = 0;
+
+ // Find the tail end of the actual encoded data even if
+ // there is/are trailing CR and/or LF.
+ while(data[tail - 1] == '=')
+ {
+ --tail;
+ if(data[tail] != '=')
+ len = tail;
+ else
+ ++eqCount;
+ }
+
+ if(eqCount > 2)
+ {
+ ok = false;
+ return;
+ }
+
+ unsigned int outIdx = 0;
+ const int count = len; // We modify len below
+ out.resize((count));
+
+ for(int idx = 0; idx < count; ++idx)
+ {
+ const unsigned char ch = data[idx];
+ if((ch > 47 && ch < 58) ||
+ (ch > 64 && ch < 91) ||
+ (ch > 96 && ch < 123) ||
+ ch == '+' ||
+ ch == '/')
+ {
+ out[outIdx++] = Base64DecMap[ch];
+ }
+ else if(ch == '=')
+ {
+ if((idx + 1) == count || data[idx + 1] == '=')
+ {
+ out[++outIdx] = Base64DecMap[ch];
+ continue;
+ }
+
+ ok = false;
+ return;
+ }
+ else if(ch == ' ')
+ {
+ /* One space is ok, and the previously applied whitespace facet(not implemented
+ * at this time of writing) have ensured it's only one space, so we assume that. */
+ --tail;
+ --len;
+ continue;
+ }
+ else
+ {
+ ok = false;
+ return;
+ }
+ }
+
+ if(outIdx % 4 != 0)
+ {
+ ok = false;
+ return;
+ }
+
+ out.resize(len);
+
+ // 4-byte to 3-byte conversion
+ len = (tail > (len / 4)) ? tail - (len / 4) : 0;
+ int sidx = 0, didx = 0;
+ if(len > 1)
+ {
+ while(didx < len - 2)
+ {
+ out[didx] =(((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
+ out[didx + 1] =(((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
+ out[didx + 2] =(((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077));
+ sidx += 4;
+ didx += 3;
+ }
+ }
+
+ if(didx < len)
+ out[didx] =(((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
+
+ if(++didx < len)
+ out[didx] =(((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
+
+ // Resize the output buffer
+ if(len == 0 || len < out.size())
+ out.resize(len);
+}
+
+AtomicValue::Ptr Base64Binary::fromLexical(const QString &str)
+{
+ const QString simple(str.simplified());
+ if(simple.isEmpty())
+ return AtomicValue::Ptr(new Base64Binary(QByteArray()));
+
+ bool ok = false;
+ QByteArray result;
+ base64Decode(simple.toUtf8(), result, ok);
+
+ if(ok)
+ return AtomicValue::Ptr(new Base64Binary(result));
+ else
+ return ValidationError::createError();
+}
+
+Base64Binary::Ptr Base64Binary::fromValue(const QByteArray &data)
+{
+ return Base64Binary::Ptr(new Base64Binary(data));
+}
+
+QString Base64Binary::stringValue() const
+{
+ return QString::fromLatin1(m_value.toBase64().constData());
+}
+
+ItemType::Ptr Base64Binary::type() const
+{
+ return BuiltinTypes::xsBase64Binary;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qbase64binary_p.h b/src/xmlpatterns/data/qbase64binary_p.h
new file mode 100644
index 0000000..f408fcd
--- /dev/null
+++ b/src/xmlpatterns/data/qbase64binary_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Base64Binary_H
+#define Patternist_Base64Binary_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the value instance of the @c xs:base64Binary type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class Base64Binary : public AtomicValue
+ {
+ public:
+ friend class CommonValues;
+
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance representing @p value.
+ */
+ static AtomicValue::Ptr fromLexical(const QString &value);
+
+ static Base64Binary::Ptr fromValue(const QByteArray &data);
+
+ virtual QString stringValue() const;
+ virtual ItemType::Ptr type() const;
+ inline const QByteArray &asByteArray() const
+ {
+ return m_value;
+ }
+
+ protected:
+ Base64Binary(const QByteArray &val);
+
+ const QByteArray m_value;
+
+ private:
+ /**
+ * @short Assumes @p in is a lexical representation of @c xs:base64Binary, and
+ * converts it to the binary data set in @p out.
+ *
+ * If @p instr is invalid Base64 content, @p ok is set to
+ * false, and the returned QByteArray has an undefined value.
+ *
+ * We cannot use QByteArray::fromBase64() because it doesn't do the
+ * necessary validation that we need to properly implement W3C XML
+ * Schema's xs:base64Binary type.
+ */
+ static void base64Decode(const QByteArray &in, QByteArray &out, bool &ok);
+
+ static const char Base64DecMap[128];
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qboolean.cpp b/src/xmlpatterns/data/qboolean.cpp
new file mode 100644
index 0000000..2f22cb3
--- /dev/null
+++ b/src/xmlpatterns/data/qboolean.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qdynamiccontext_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qboolean_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool Boolean::evaluateEBV(const Item::Iterator::Ptr &it,
+ const QExplicitlySharedDataPointer<DynamicContext> &context)
+{
+ return evaluateEBV(it->next(), it, context);
+}
+
+bool Boolean::evaluateEBV(const Item &first,
+ const Item::Iterator::Ptr &it,
+ const QExplicitlySharedDataPointer<DynamicContext> &context)
+{
+ Q_ASSERT(it);
+ Q_ASSERT(context);
+
+ if(!first)
+ return false;
+ else if(first.isNode())
+ return true;
+
+ const Item second(it->next());
+
+ if(second)
+ {
+ Q_ASSERT(context);
+ context->error(QtXmlPatterns::tr("Effective Boolean Value cannot be calculated for a sequence "
+ "containing two or more atomic values."),
+ ReportContext::FORG0006,
+ QSourceLocation());
+ return false;
+ }
+ else
+ return first.as<AtomicValue>()->evaluateEBV(context);
+}
+
+bool Boolean::evaluateEBV(const Item &item,
+ const QExplicitlySharedDataPointer<DynamicContext> &context)
+{
+ if(!item)
+ return false;
+ else if(item.isNode())
+ return true;
+ else
+ return item.as<AtomicValue>()->evaluateEBV(context);
+}
+
+Boolean::Boolean(const bool value) : m_value(value)
+{
+}
+
+QString Boolean::stringValue() const
+{
+ return m_value
+ ? CommonValues::TrueString->stringValue()
+ : CommonValues::FalseString->stringValue();
+}
+
+bool Boolean::evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return m_value;
+}
+
+Boolean::Ptr Boolean::fromValue(const bool value)
+{
+ return value ? CommonValues::BooleanTrue : CommonValues::BooleanFalse;
+}
+
+AtomicValue::Ptr Boolean::fromLexical(const QString &lexical)
+{
+ const QString val(lexical.trimmed()); /* Apply the whitespace facet. */
+
+ if(val == QLatin1String("true") || val == QChar(QLatin1Char('1')))
+ return CommonValues::BooleanTrue;
+ else if(val == QLatin1String("false") || val == QChar(QLatin1Char('0')))
+ return CommonValues::BooleanFalse;
+ else
+ return ValidationError::createError();
+}
+
+ItemType::Ptr Boolean::type() const
+{
+ return BuiltinTypes::xsBoolean;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qboolean_p.h b/src/xmlpatterns/data/qboolean_p.h
new file mode 100644
index 0000000..da69e8b
--- /dev/null
+++ b/src/xmlpatterns/data/qboolean_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Boolean_H
+#define Patternist_Boolean_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:boolean type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class Q_AUTOTEST_EXPORT Boolean : public AtomicValue
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * @returns the boolean value this Boolean represents
+ */
+ static bool evaluateEBV(const Item::Iterator::Ptr &e,
+ const QExplicitlySharedDataPointer<DynamicContext> &);
+
+ static bool evaluateEBV(const Item &first,
+ const Item::Iterator::Ptr &e,
+ const QExplicitlySharedDataPointer<DynamicContext> &);
+
+ static bool evaluateEBV(const Item &item,
+ const QExplicitlySharedDataPointer<DynamicContext> &context);
+
+ virtual QString stringValue() const;
+
+ /**
+ * @returns a Boolean object instantiating @p value. Use True() or False()
+ * if you already know what value you need.
+ */
+ static Boolean::Ptr fromValue(const bool value);
+
+ /**
+ * Creates a boolean value from a lexical representation. "true" and "1"
+ * becomes @c true, while "false" and "0" becomes @c false.
+ */
+ static AtomicValue::Ptr fromLexical(const QString &val);
+
+ /**
+ * Get the Effective %Boolean Value of this boolean value. For <tt>xs:boolean</tt>, this
+ * is simply the value.
+ */
+ virtual bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const;
+
+ virtual ItemType::Ptr type() const;
+
+ inline bool value() const
+ {
+ return m_value;
+ }
+
+ protected:
+ friend class CommonValues;
+ Boolean(const bool value);
+
+ private:
+ const bool m_value;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qcommonvalues.cpp b/src/xmlpatterns/data/qcommonvalues.cpp
new file mode 100644
index 0000000..88beeea
--- /dev/null
+++ b/src/xmlpatterns/data/qcommonvalues.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <limits>
+
+#include "qabstractfloat_p.h"
+#include "qanyuri_p.h"
+#include "qboolean_p.h"
+#include "qdecimal_p.h"
+#include "qinteger_p.h"
+#include "qatomicstring_p.h"
+#include "quntypedatomic_p.h"
+
+#include "qcommonvalues_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+// STATIC DATA
+const AtomicString::Ptr CommonValues::EmptyString
+ (new AtomicString(QLatin1String("")));
+const AtomicString::Ptr CommonValues::TrueString
+ (new AtomicString(QLatin1String("true")));
+const AtomicString::Ptr CommonValues::FalseString
+ (new AtomicString(QLatin1String("false")));
+
+const UntypedAtomic::Ptr CommonValues::UntypedAtomicTrue
+ (new UntypedAtomic(QLatin1String("true")));
+const UntypedAtomic::Ptr CommonValues::UntypedAtomicFalse
+ (new UntypedAtomic(QLatin1String("false")));
+
+const AtomicValue::Ptr CommonValues::BooleanTrue
+ (new Boolean(true));
+const AtomicValue::Ptr CommonValues::BooleanFalse(new Boolean(false));
+
+const AtomicValue::Ptr CommonValues::DoubleNaN
+ (Double::fromValue(std::numeric_limits<xsDouble>::quiet_NaN()));
+
+const AtomicValue::Ptr CommonValues::FloatNaN
+ (Float::fromValue(std::numeric_limits<xsFloat>::quiet_NaN()));
+
+const Item CommonValues::IntegerZero
+ (Integer::fromValue(0));
+
+const AtomicValue::Ptr CommonValues::EmptyAnyURI
+ (AnyURI::fromValue(QLatin1String("")));
+
+const AtomicValue::Ptr CommonValues::DoubleOne
+ (Double::fromValue(1));
+const AtomicValue::Ptr CommonValues::FloatOne
+ (Float::fromValue(1));
+const AtomicValue::Ptr CommonValues::DecimalOne
+ (Decimal::fromValue(1));
+const Item CommonValues::IntegerOne
+ (Integer::fromValue(1));
+const Item CommonValues::IntegerOneNegative
+ (Integer::fromValue(-1));
+
+const AtomicValue::Ptr CommonValues::DoubleZero
+ (Double::fromValue(0));
+const AtomicValue::Ptr CommonValues::FloatZero
+ (Float::fromValue(0));
+const AtomicValue::Ptr CommonValues::DecimalZero
+ (Decimal::fromValue(0));
+
+const Item::EmptyIterator::Ptr CommonValues::emptyIterator
+ (new Item::EmptyIterator());
+
+const AtomicValue::Ptr CommonValues::NegativeInfDouble
+ (Double::fromValue(-std::numeric_limits<xsDouble>::infinity()));
+const AtomicValue::Ptr CommonValues::InfDouble
+ (Double::fromValue(std::numeric_limits<xsDouble>::infinity()));
+const AtomicValue::Ptr CommonValues::NegativeInfFloat
+ (Float::fromValue(-std::numeric_limits<xsFloat>::infinity()));
+const AtomicValue::Ptr CommonValues::InfFloat
+ (Float::fromValue(std::numeric_limits<xsFloat>::infinity()));
+
+const DayTimeDuration::Ptr CommonValues::DayTimeDurationZero
+ (DayTimeDuration::fromSeconds(0));
+const DayTimeDuration::Ptr CommonValues::YearMonthDurationZero
+ (YearMonthDuration::fromComponents(true, 0, 0));
+
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qcommonvalues_p.h b/src/xmlpatterns/data/qcommonvalues_p.h
new file mode 100644
index 0000000..cd3e270
--- /dev/null
+++ b/src/xmlpatterns/data/qcommonvalues_p.h
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CommonValues_H
+#define Patternist_CommonValues_H
+
+#include "qdaytimeduration_p.h"
+#include "qyearmonthduration_p.h"
+#include "qemptyiterator_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short A collection of common values.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo Documentation is missing/incomplete
+ */
+ class CommonValues
+ {
+ public:
+ /**
+ * An empty, zero-length string.
+ *
+ * @note It is not @c null, but empty.
+ */
+ static const AtomicValue::Ptr EmptyString;
+
+ /**
+ * The string "true", the lexical representation of
+ * @c xs:boolean's value @c true.
+ */
+ static const AtomicValue::Ptr TrueString;
+
+ /**
+ * The string "false", the lexical representation of
+ * @c xs:boolean's value @c false.
+ */
+ static const AtomicValue::Ptr UntypedAtomicFalse;
+
+ /**
+ * The string "true", the lexical representation of
+ * @c xs:boolean's value @c true.
+ */
+ static const AtomicValue::Ptr UntypedAtomicTrue;
+
+ /**
+ * The string "false", the lexical representation of
+ * @c xs:boolean's value @c false.
+ */
+ static const AtomicValue::Ptr FalseString;
+
+ /**
+ * @returns a Boolean instance carrying the boolean value @c true.
+ * Use this value instead of Boolean::fromValue() if you
+ * know what boolean value you need.
+ */
+ static const AtomicValue::Ptr BooleanTrue;
+
+ /**
+ * @returns a Boolean instance carrying the boolean value @c true.
+ * Use this value instead of Boolean::fromValue() if you
+ * know what boolean value you need.
+ */
+ static const AtomicValue::Ptr BooleanFalse;
+
+ /**
+ * Not-a-Numeric typed as @c xs:double.
+ */
+ static const AtomicValue::Ptr DoubleNaN;
+
+ /**
+ * Not-a-Number typed as @c xs:float, <tt>xs:float("NaN")</tt>.
+ */
+ static const AtomicValue::Ptr FloatNaN;
+
+ /**
+ * Zero(0) typed as @c xs:integer, <tt>xs:integer("0")</tt>.
+ */
+ static const Item IntegerZero;
+
+ /**
+ * An empty, "", @c xs:anyURI.
+ */
+ static const AtomicValue::Ptr EmptyAnyURI;
+
+ /**
+ * The empty sequence.
+ */
+ static const EmptyIterator<Item>::Ptr emptyIterator;
+
+ /**
+ * <tt>xs:float("-INF")</tt>
+ */
+ static const AtomicValue::Ptr NegativeInfFloat;
+
+ /**
+ * <tt>xs:float("INF")</tt>
+ */
+ static const AtomicValue::Ptr InfFloat;
+
+ /**
+ * <tt>xs:double("-INF")</tt>
+ */
+ static const AtomicValue::Ptr NegativeInfDouble;
+
+ /**
+ * <tt>xs:double("INF")</tt>
+ */
+ static const AtomicValue::Ptr InfDouble;
+
+ /**
+ * <tt>xs:float("1")</tt>
+ */
+ static const AtomicValue::Ptr FloatOne;
+ /**
+ * <tt>xs:double("1")</tt>
+ */
+ static const AtomicValue::Ptr DoubleOne;
+ /**
+ * <tt>xs:decimal("1")</tt>
+ */
+ static const AtomicValue::Ptr DecimalOne;
+
+ /**
+ * <tt>xs:integer("1")</tt>
+ */
+ static const Item IntegerOne;
+
+ /**
+ * <tt>xs:integer("-1")</tt>
+ */
+ static const Item IntegerOneNegative;
+
+ /**
+ * <tt>xs:double("0")</tt>
+ */
+ static const AtomicValue::Ptr DoubleZero;
+
+ /**
+ * <tt>xs:float("0")</tt>
+ */
+ static const AtomicValue::Ptr FloatZero;
+ /**
+ * <tt>xs:integer("0")</tt>
+ */
+ static const AtomicValue::Ptr DecimalZero;
+
+ /**
+ * The @c xs:dayTimeDuration value PT0S
+ */
+ static const DayTimeDuration::Ptr DayTimeDurationZero;
+
+ /**
+ * The @c xs:yearMonthDuration value P0M
+ */
+ static const DayTimeDuration::Ptr YearMonthDurationZero;
+
+ private:
+ /**
+ * The constructor is private because this class is not meant to be instantiated,
+ * but should only be used via its static const members.
+ */
+ inline CommonValues();
+
+ Q_DISABLE_COPY(CommonValues)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qcomparisonfactory.cpp b/src/xmlpatterns/data/qcomparisonfactory.cpp
new file mode 100644
index 0000000..66d72af
--- /dev/null
+++ b/src/xmlpatterns/data/qcomparisonfactory.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomiccomparators_p.h"
+#include "qatomicstring_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qvaluefactory_p.h"
+
+#include "qcomparisonfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/**
+ * @short Helper class for ComparisonFactory::fromLexical() which exposes
+ * CastingPlatform appropriately.
+ *
+ * @relates ComparisonFactory
+ */
+class PerformComparison : public ComparisonPlatform<PerformComparison, true>
+ , public SourceLocationReflection
+{
+public:
+ PerformComparison(const SourceLocationReflection *const sourceLocationReflection,
+ const AtomicComparator::Operator op) : m_sourceReflection(sourceLocationReflection)
+ , m_operator(op)
+ {
+ Q_ASSERT(m_sourceReflection);
+ }
+
+ bool operator()(const AtomicValue::Ptr &operand1,
+ const AtomicValue::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context)
+ {
+ const ItemType::Ptr asItemType((AtomicType::Ptr(type)));
+
+ /* One area where the Query Transform world differs from the Schema
+ * world is that @c xs:duration is not considedered comparable, because
+ * it's according to Schema is partially comparable. This means
+ * ComparisonPlatform::fetchComparator() flags it as impossible, and
+ * hence we need to override that.
+ *
+ * SchemaType::wxsTypeMatches() will return true for sub-types of @c
+ * xs:duration as well, but that's ok since AbstractDurationComparator
+ * works for them too. */
+ if(BuiltinTypes::xsDuration->wxsTypeMatches(type))
+ prepareComparison(AtomicComparator::Ptr(new AbstractDurationComparator()));
+ else if (BuiltinTypes::xsGYear->wxsTypeMatches(type) ||
+ BuiltinTypes::xsGYearMonth->wxsTypeMatches(type) ||
+ BuiltinTypes::xsGMonth->wxsTypeMatches(type) ||
+ BuiltinTypes::xsGMonthDay->wxsTypeMatches(type) ||
+ BuiltinTypes::xsGDay->wxsTypeMatches(type))
+ prepareComparison(AtomicComparator::Ptr(new AbstractDateTimeComparator()));
+ else
+ prepareComparison(fetchComparator(asItemType, asItemType, context));
+
+ return flexibleCompare(operand1, operand2, context);
+ }
+
+ const SourceLocationReflection *actualReflection() const
+ {
+ return m_sourceReflection;
+ }
+
+ AtomicComparator::Operator operatorID() const
+ {
+ return m_operator;
+ }
+
+private:
+ const SourceLocationReflection *const m_sourceReflection;
+ const AtomicComparator::Operator m_operator;
+};
+
+bool ComparisonFactory::compare(const AtomicValue::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const AtomicValue::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection)
+{
+ Q_ASSERT(operand1);
+ Q_ASSERT(operand2);
+ Q_ASSERT(context);
+ Q_ASSERT(sourceLocationReflection);
+ Q_ASSERT(type);
+ Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO,
+ "We can only compare atomic values.");
+
+ return PerformComparison(sourceLocationReflection, op)(operand1, operand2, type, context);
+}
+
+bool ComparisonFactory::constructAndCompare(const DerivedString<TypeString>::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const DerivedString<TypeString>::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection)
+{
+ Q_ASSERT(operand1);
+ Q_ASSERT(operand2);
+ Q_ASSERT(context);
+ Q_ASSERT(sourceLocationReflection);
+ Q_ASSERT(type);
+ Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO,
+ "We can only compare atomic values.");
+
+ const AtomicValue::Ptr value1 = ValueFactory::fromLexical(operand1->stringValue(), type, context, sourceLocationReflection);
+ const AtomicValue::Ptr value2 = ValueFactory::fromLexical(operand2->stringValue(), type, context, sourceLocationReflection);
+
+ return compare(value1, op, value2, type, context, sourceLocationReflection);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qcomparisonfactory_p.h b/src/xmlpatterns/data/qcomparisonfactory_p.h
new file mode 100644
index 0000000..61f65b1
--- /dev/null
+++ b/src/xmlpatterns/data/qcomparisonfactory_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ComparisonFactory_H
+#define Patternist_ComparisonFactory_H
+
+#include "qatomiccomparator_p.h"
+#include "qderivedstring_p.h"
+#include "qitem_p.h"
+#include "qreportcontext_p.h"
+#include "qschematype_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides compare(), which is a high-level helper function for
+ * comparing atomic values.
+ *
+ * This class wraps the helper class ComparisonPlatform with a more specific,
+ * high-level API.
+ *
+ * @see ComparisonPlatform
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_schema
+ */
+ class ComparisonFactory
+ {
+ public:
+ /**
+ * @short Returns the result of evaluating operator @p op applied to the atomic
+ * values @p operand1 and @p operand2.
+ *
+ * The caller guarantees that both values are of type @p type.
+ *
+ * ComparisonFactory does not take ownership of @p sourceLocationReflection.
+ */
+ static bool compare(const AtomicValue::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const AtomicValue::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection);
+
+ /**
+ * @short Returns the result of evaluating operator @p op applied to the atomic
+ * values @p operand1 and @p operand2.
+ *
+ * In opposite to compare() it converts the operands from string type
+ * to @p type and compares these constructed types.
+ *
+ * The caller guarantees that both values are of type @p type.
+ *
+ * ComparisonFactory does not take ownership of @p sourceLocationReflection.
+ */
+ static bool constructAndCompare(const DerivedString<TypeString>::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const DerivedString<TypeString>::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection);
+
+ private:
+ Q_DISABLE_COPY(ComparisonFactory)
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qdate.cpp b/src/xmlpatterns/data/qdate.cpp
new file mode 100644
index 0000000..cc0842b
--- /dev/null
+++ b/src/xmlpatterns/data/qdate.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+
+#include "qdate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Date::Date(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+Date::Ptr Date::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(-?)" /* Any preceding minus. */
+ "(\\d{4,})" /* The year part. */
+ "-" /* Delimiter. */
+ "(\\d{2})" /* The month part. */
+ "-" /* Delimiter. */
+ "(\\d{2})" /* The day part. */
+ "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*zoneOffsetSignP*/ 5,
+ /*zoneOffsetHourP*/ 6,
+ /*zoneOffsetMinuteP*/ 7,
+ /*zoneOffsetUTCSymbolP*/ 8,
+ /*yearP*/ 2,
+ /*monthP*/ 3,
+ /*dayP*/ 4,
+ /*hourP*/ -1,
+ /*minutesP*/ -1,
+ /*secondsP*/ -1,
+ /*msecondsP*/ -1,
+ /*yearSign*/ 1);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : Date::Ptr(new Date(retval));
+}
+
+Date::Ptr Date::fromDateTime(const QDateTime &date)
+{
+ /* Don't include the QTime; "reset" the time. */
+ QDateTime result;
+ copyTimeSpec(date, result);
+ result.setDate(date.date());
+ Q_ASSERT(date.isValid());
+
+ return Date::Ptr(new Date(result));
+}
+
+Item Date::fromValue(const QDateTime &dt) const
+{
+ Q_ASSERT(dt.isValid());
+ return fromDateTime(dt);
+}
+
+QString Date::stringValue() const
+{
+ return dateToString() + zoneOffsetToString();
+}
+
+ItemType::Ptr Date::type() const
+{
+ return BuiltinTypes::xsDate;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qdate_p.h b/src/xmlpatterns/data/qdate_p.h
new file mode 100644
index 0000000..000da2e
--- /dev/null
+++ b/src/xmlpatterns/data/qdate_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Date_H
+#define Patternist_Date_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:date type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class Date : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static Date::Ptr fromLexical(const QString &string);
+ static Date::Ptr fromDateTime(const QDateTime &date);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+ virtual Item fromValue(const QDateTime &dt) const;
+
+ protected:
+ friend class CommonValues;
+
+ Date(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qdaytimeduration.cpp b/src/xmlpatterns/data/qdaytimeduration.cpp
new file mode 100644
index 0000000..e47144c
--- /dev/null
+++ b/src/xmlpatterns/data/qdaytimeduration.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractdatetime_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonvalues_p.h"
+
+#include "qdaytimeduration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DayTimeDuration::DayTimeDuration(const bool isPositiveP,
+ const DayCountProperty daysP,
+ const HourProperty hoursP,
+ const MinuteProperty minutesP,
+ const SecondProperty secs,
+ const MSecondProperty msecs) : AbstractDuration(isPositiveP),
+ m_days(daysP),
+ m_hours(hoursP),
+ m_minutes(minutesP),
+ m_seconds(secs),
+ m_mseconds(msecs)
+{
+}
+
+DayTimeDuration::Ptr DayTimeDuration::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable(
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(-)?" /* Any minus sign. */
+ "P" /* Delimiter. */
+ "(?:(\\d+)D)?" /* Day part. */
+ "(?:" /* Here starts the optional time part. */
+ "(T)" /* SchemaTime delimiter. */
+ "(?:(\\d+)H)?" /* Hour part. */
+ "(?:(\\d+)M)?" /* Minute part. */
+ "(?:(\\d+)(?:\\.(\\d+))?S)?" /* Seconds & milli seconds. */
+ ")?" /* End of optional time part. */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*yearP*/ -1,
+ /*monthP*/ -1,
+ /*dayP*/ 2,
+ /*tDelimiterP*/ 3,
+ /*hourP*/ 4,
+ /*minutesP*/ 5,
+ /*secondsP*/ 6,
+ /*msecondsP*/ 7);
+
+ DayCountProperty days = 0;
+ HourProperty hours = 0;
+ MinuteProperty minutes = 0;
+ SecondProperty sec = 0;
+ MSecondProperty msec = 0;
+ bool isPos;
+
+ const DayTimeDuration::Ptr err(create(captureTable, lexical, &isPos, 0, 0, &days,
+ &hours, &minutes, &sec, &msec));
+ return err ? err : DayTimeDuration::Ptr(new DayTimeDuration(isPos, days, hours, minutes,
+ sec, msec));
+}
+
+DayTimeDuration::Ptr DayTimeDuration::fromComponents(const bool isPositive,
+ const DayCountProperty days,
+ const HourProperty hours,
+ const MinuteProperty minutes,
+ const SecondProperty seconds,
+ const MSecondProperty mseconds)
+{
+ return DayTimeDuration::Ptr(new DayTimeDuration(isPositive,
+ days,
+ hours,
+ minutes,
+ seconds,
+ mseconds));
+}
+
+DayTimeDuration::Ptr DayTimeDuration::fromSeconds(const SecondCountProperty sourceSecs,
+ const MSecondProperty msecs)
+{
+ Q_ASSERT(msecs >= 0);
+ const SecondCountProperty source = qAbs(sourceSecs);
+ const bool isPos = sourceSecs >= 0;
+ const SecondCountProperty secs = source % 60;
+ const MinuteCountProperty mins = (source / 60) % 60;
+ const HourCountProperty hours = source / (60 * 60) % 24;
+ const DayCountProperty days = source / (60 * 60) / 24;
+
+ return DayTimeDuration::Ptr(new DayTimeDuration(isPos, days, hours, mins, secs, msecs));
+}
+
+QString DayTimeDuration::stringValue() const
+{
+ QString retval;
+
+ if(!m_isPositive)
+ retval.append(QLatin1Char('-'));
+
+ retval.append(QLatin1Char('P'));
+
+ if(m_days)
+ {
+ retval.append(QString::number(m_days));
+ retval.append(QLatin1Char('D'));
+ }
+
+ if(!m_hours && !m_minutes && !m_seconds && !m_seconds)
+ {
+ if(!m_days)
+ return QLatin1String("PT0S");
+ else
+ return retval;
+ }
+
+ retval.append(QLatin1Char('T'));
+
+ if(m_hours)
+ {
+ retval.append(QString::number(m_hours));
+ retval.append(QLatin1Char('H'));
+ }
+
+ if(m_minutes)
+ {
+ retval.append(QString::number(m_minutes));
+ retval.append(QLatin1Char('M'));
+ }
+
+ if(m_seconds || m_seconds)
+ {
+ retval.append(QString::number(m_seconds));
+
+ if(m_mseconds)
+ retval.append(serializeMSeconds(m_mseconds));
+
+ retval.append(QLatin1Char('S'));
+ }
+ else if(!m_days && !m_hours && !m_minutes)
+ retval.append(QLatin1String("0S"));
+
+ return retval;
+}
+
+AbstractDuration::Value DayTimeDuration::value() const
+{
+ return ((m_days * 24 * 60 * 60 * 1000) +
+ (m_hours * 60 * 60 * 1000) +
+ (m_minutes * 60 * 1000) +
+ (m_seconds * 1000) +
+ m_mseconds) * (m_isPositive ? 1 : -1);
+}
+
+Item DayTimeDuration::fromValue(const Value val) const
+{
+ if(val == 0)
+ return toItem(CommonValues::DayTimeDurationZero);
+ else
+ return toItem(fromSeconds(val / 1000, qAbs(val) % 1000));
+}
+
+ItemType::Ptr DayTimeDuration::type() const
+{
+ return BuiltinTypes::xsDayTimeDuration;
+}
+
+YearProperty DayTimeDuration::years() const
+{
+ return 0;
+}
+
+MonthProperty DayTimeDuration::months() const
+{
+ return 0;
+}
+
+DayCountProperty DayTimeDuration::days() const
+{
+ return m_days;
+}
+
+HourProperty DayTimeDuration::hours() const
+{
+ return m_hours;
+}
+
+MinuteProperty DayTimeDuration::minutes() const
+{
+ return m_minutes;
+}
+
+SecondProperty DayTimeDuration::seconds() const
+{
+ return m_seconds;
+}
+
+MSecondProperty DayTimeDuration::mseconds() const
+{
+ return m_mseconds;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qdaytimeduration_p.h b/src/xmlpatterns/data/qdaytimeduration_p.h
new file mode 100644
index 0000000..f9eb524
--- /dev/null
+++ b/src/xmlpatterns/data/qdaytimeduration_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DayTimeDuration_H
+#define Patternist_DayTimeDuration_H
+
+#include "qabstractduration_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:dayTimeDuration type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class DayTimeDuration : public AbstractDuration
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<DayTimeDuration> Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static DayTimeDuration::Ptr fromLexical(const QString &string);
+
+ static DayTimeDuration::Ptr fromComponents(const bool isPositive,
+ const DayCountProperty days,
+ const HourProperty hours,
+ const MinuteProperty minutes,
+ const SecondProperty seconds,
+ const MSecondProperty mseconds);
+ /**
+ * Creates a DayTimeDuration that has the value expressed in seconds @p secs
+ * and milli seconds @p msecs. The signedness of @p secs communicates
+ * whether this DayTimeDuration is positive or negative. @p msecs must always
+ * be positive.
+ */
+ static DayTimeDuration::Ptr fromSeconds(const SecondCountProperty secs,
+ const MSecondProperty msecs = 0);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+
+ /**
+ * @returns always 0.
+ */
+ virtual YearProperty years() const;
+
+ /**
+ * @returns always 0.
+ */
+ virtual MonthProperty months() const;
+ virtual DayCountProperty days() const;
+ virtual HourProperty hours() const;
+ virtual MinuteProperty minutes() const;
+ virtual MSecondProperty mseconds() const;
+ virtual SecondProperty seconds() const;
+
+ /**
+ * @returns the value of this xs:dayTimeDuration
+ * in milli seconds.
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#dt-dayTimeDuration">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 10.3.2.2 Calculating the value of a
+ * xs:dayTimeDuration from the lexical representation</a>
+ */
+ virtual Value value() const;
+
+ /**
+ * Creates a DayTimeDuration containing the value @p val. @p val is
+ * expressed in milli seconds.
+ *
+ * If @p val is zero, is CommonValues::DayTimeDurationZero returned.
+ */
+ virtual Item fromValue(const Value val) const;
+
+ protected:
+ friend class CommonValues;
+
+ DayTimeDuration(const bool isPositive,
+ const DayCountProperty days,
+ const HourProperty hours,
+ const MinuteProperty minutes,
+ const SecondProperty seconds,
+ const MSecondProperty mseconds);
+
+ private:
+ const DayCountProperty m_days;
+ const HourProperty m_hours;
+ const MinuteProperty m_minutes;
+ const SecondProperty m_seconds;
+ const MSecondProperty m_mseconds;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qdecimal.cpp b/src/xmlpatterns/data/qdecimal.cpp
new file mode 100644
index 0000000..0003a08
--- /dev/null
+++ b/src/xmlpatterns/data/qdecimal.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <math.h>
+
+#include "qabstractfloat_p.h"
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qdecimal_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Decimal::Decimal(const xsDecimal num) : m_value(num)
+{
+}
+
+Decimal::Ptr Decimal::fromValue(const xsDecimal num)
+{
+ return Decimal::Ptr(new Decimal(num));
+}
+
+AtomicValue::Ptr Decimal::fromLexical(const QString &strNumeric)
+{
+ /* QString::toDouble() handles the whitespace facet. */
+ const QString strNumericTrimmed(strNumeric.trimmed());
+
+ /* Block these out, as QString::toDouble() supports them. */
+ if(strNumericTrimmed.compare(QLatin1String("-INF"), Qt::CaseInsensitive) == 0
+ || strNumericTrimmed.compare(QLatin1String("INF"), Qt::CaseInsensitive) == 0
+ || strNumericTrimmed.compare(QLatin1String("+INF"), Qt::CaseInsensitive) == 0
+ || strNumericTrimmed.compare(QLatin1String("nan"), Qt::CaseInsensitive) == 0
+ || strNumericTrimmed.contains(QLatin1Char('e'))
+ || strNumericTrimmed.contains(QLatin1Char('E')))
+ {
+ return ValidationError::createError();
+ }
+
+ bool conversionOk = false;
+ const xsDecimal num = strNumericTrimmed.toDouble(&conversionOk);
+
+ if(conversionOk)
+ return AtomicValue::Ptr(new Decimal(num));
+ else
+ return ValidationError::createError();
+}
+
+bool Decimal::evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return !Double::isEqual(m_value, 0.0);
+}
+
+QString Decimal::stringValue() const
+{
+ return toString(m_value);
+}
+
+QString Decimal::toString(const xsDecimal value)
+{
+ /*
+ * If SV is in the value space of xs:integer, that is, if there are no
+ * significant digits after the decimal point, then the value is converted
+ * from an xs:decimal to an xs:integer and the resulting xs:integer is
+ * converted to an xs:string using the rule above.
+ */
+ if(Double::isEqual(::floor(value), value))
+ {
+ /* The static_cast is identical to Integer::toInteger(). */
+ return QString::number(static_cast<xsInteger>(value));
+ }
+ else
+ {
+ int sign;
+ int decimalPoint;
+ char *result = 0;
+ static_cast<void>(qdtoa(value, 0, 0, &decimalPoint, &sign, 0, &result));
+ /* If the copy constructor is used instead of QString::operator=(),
+ * it doesn't compile. I have no idea why. */
+ const QString qret(QString::fromLatin1(result));
+ delete result;
+
+ QString valueAsString;
+
+ if(sign)
+ valueAsString += QLatin1Char('-');
+
+ if(0 < decimalPoint)
+ {
+ valueAsString += qret.left(decimalPoint);
+ valueAsString += QLatin1Char('.');
+ if (qret.size() <= decimalPoint)
+ valueAsString += QLatin1Char('0');
+ else
+ valueAsString += qret.mid(decimalPoint);
+ }
+ else
+ {
+ valueAsString += QLatin1Char('0');
+ valueAsString += QLatin1Char('.');
+
+ for(int d = decimalPoint; d < 0; d++)
+ valueAsString += QLatin1Char('0');
+
+ valueAsString += qret;
+ }
+
+ return valueAsString;
+ }
+}
+
+ItemType::Ptr Decimal::type() const
+{
+ return BuiltinTypes::xsDecimal;
+}
+
+xsDouble Decimal::toDouble() const
+{
+ return static_cast<xsDouble>(m_value);
+}
+
+xsInteger Decimal::toInteger() const
+{
+ return static_cast<xsInteger>(m_value);
+}
+
+xsFloat Decimal::toFloat() const
+{
+ return static_cast<xsFloat>(m_value);
+}
+
+xsDecimal Decimal::toDecimal() const
+{
+ return m_value;
+}
+
+qulonglong Decimal::toUnsignedInteger() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function, see Numeric::toUnsignedInteger().");
+ return 0;
+}
+
+Numeric::Ptr Decimal::round() const
+{
+ return Numeric::Ptr(new Decimal(roundFloat(m_value)));
+}
+
+Numeric::Ptr Decimal::roundHalfToEven(const xsInteger /*scale*/) const
+{
+ return Numeric::Ptr();
+}
+
+Numeric::Ptr Decimal::floor() const
+{
+ return Numeric::Ptr(new Decimal(static_cast<xsDecimal>(::floor(m_value))));
+}
+
+Numeric::Ptr Decimal::ceiling() const
+{
+ return Numeric::Ptr(new Decimal(static_cast<xsDecimal>(ceil(m_value))));
+}
+
+Numeric::Ptr Decimal::abs() const
+{
+ return Numeric::Ptr(new Decimal(static_cast<xsDecimal>(fabs(m_value))));
+}
+
+bool Decimal::isNaN() const
+{
+ return false;
+}
+
+bool Decimal::isInf() const
+{
+ return false;
+}
+
+Item Decimal::toNegated() const
+{
+ if(AbstractFloat<true>::isEqual(m_value, 0.0))
+ return fromValue(0).data();
+ else
+ return fromValue(-m_value).data();
+}
+
+bool Decimal::isSigned() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function, see Numeric::isSigned().");
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qdecimal_p.h b/src/xmlpatterns/data/qdecimal_p.h
new file mode 100644
index 0000000..9b9a804
--- /dev/null
+++ b/src/xmlpatterns/data/qdecimal_p.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Decimal_H
+#define Patternist_Decimal_H
+
+#include "qschemanumeric_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * Defined in QtCore's qlocale.cpp.
+ */
+Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp);
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the value instance of the @c xs:decimal type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo Documentation is missing/incomplete
+ */
+ class Decimal : public Numeric
+ {
+ public:
+
+ static Decimal::Ptr fromValue(const xsDecimal num);
+
+ /**
+ * Creates a Decimal from the lexical representation of @c xs:decimal stored in
+ * @p strNumeric.
+ *
+ * A possible optimization is to create an Integer if the string ends
+ * with ".0". But this is not conformant. For example, the user writes N.0
+ * which according to the specification is an xs:decimal, but where the
+ * expression is, is an xs:integer is required. That would pass with
+ * such an optimization.
+ */
+ static AtomicValue::Ptr fromLexical(const QString &strNumeric);
+
+ /**
+ * Gets the Effective %Boolean Value of this number.
+ *
+ * @returns @c false if the number is 0 or @c NaN, otherwise @c true.
+ */
+ bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const;
+
+ virtual QString stringValue() const;
+
+ /**
+ * @returns always BuiltinTypes::xsDecimal
+ */
+ virtual ItemType::Ptr type() const;
+
+ virtual xsDouble toDouble() const;
+ virtual xsInteger toInteger() const;
+ virtual xsFloat toFloat() const;
+ virtual xsDecimal toDecimal() const;
+ virtual qulonglong toUnsignedInteger() const;
+
+ virtual Numeric::Ptr round() const;
+ virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const;
+ virtual Numeric::Ptr floor() const;
+ virtual Numeric::Ptr ceiling() const;
+ virtual Numeric::Ptr abs() const;
+
+ /**
+ * @returns always @c false, xs:decimal doesn't have
+ * not-a-number in its value space.
+ */
+ virtual bool isNaN() const;
+
+ /**
+ * @returns always @c false, xs:decimal doesn't have
+ * infinity in its value space.
+ */
+ virtual bool isInf() const;
+
+ virtual Item toNegated() const;
+
+ /**
+ * Converts @p value into a canonical string representation for @c xs:decimal. This
+ * function is used internally by various classes. Users probably wants to call
+ * stringValue() which in turn calls this function.
+ */
+ static QString toString(const xsDecimal value);
+
+ virtual bool isSigned() const;
+
+ protected:
+
+ Decimal(const xsDecimal num);
+
+ private:
+ const xsDecimal m_value;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qderivedinteger_p.h b/src/xmlpatterns/data/qderivedinteger_p.h
new file mode 100644
index 0000000..0ef5b51
--- /dev/null
+++ b/src/xmlpatterns/data/qderivedinteger_p.h
@@ -0,0 +1,624 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DerivedInteger_H
+#define Patternist_DerivedInteger_H
+
+#include "qbuiltintypes_p.h"
+#include "qinteger_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvalidationerror_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @relates DerivedInteger
+ */
+ enum DerivedIntegerLimitsUsage
+ {
+ None = 1,
+ LimitUpwards = 2,
+ LimitDownwards = 4,
+ LimitBoth = LimitUpwards | LimitDownwards
+ };
+
+ enum
+ {
+ IgnorableSignedValue = 0,
+ IgnorableUnsignedValue = 0
+ };
+
+ template<TypeOfDerivedInteger DerivedType> class DerivedInteger;
+
+ template<TypeOfDerivedInteger DerivedType> class DerivedIntegerDetails;
+
+ template<>
+ class DerivedIntegerDetails<TypeByte>
+ {
+ private:
+ friend class DerivedInteger<TypeByte>;
+ typedef qint8 StorageType;
+ typedef xsInteger TemporaryStorageType;
+ static const StorageType maxInclusive = 127;
+ static const StorageType minInclusive = -128;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeInt>
+ {
+ private:
+ friend class DerivedInteger<TypeInt>;
+ typedef qint32 StorageType;
+ typedef xsInteger TemporaryStorageType;
+ static const StorageType maxInclusive = Q_INT64_C(2147483647);
+ static const StorageType minInclusive = Q_INT64_C(-2147483648);
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeLong>
+ {
+ private:
+ friend class DerivedInteger<TypeLong>;
+ typedef qint64 StorageType;
+ typedef StorageType TemporaryStorageType;
+ static const StorageType maxInclusive = Q_INT64_C(9223372036854775807);
+
+ /**
+ * This messy arithmetic expression ensures that we don't get a warning
+ * on neither GCC nor MSVC.
+ */
+ static const StorageType minInclusive = -(Q_INT64_C(9223372036854775807)) - 1;
+
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeNegativeInteger>
+ {
+ private:
+ friend class DerivedInteger<TypeNegativeInteger>;
+ typedef xsInteger StorageType;
+ typedef StorageType TemporaryStorageType;
+ static const StorageType maxInclusive = -1;
+ static const StorageType minInclusive = IgnorableSignedValue;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitUpwards;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeNonNegativeInteger>
+ {
+ private:
+ friend class DerivedInteger<TypeNonNegativeInteger>;
+ typedef xsInteger StorageType;
+ typedef StorageType TemporaryStorageType;
+ static const StorageType maxInclusive = IgnorableSignedValue;
+ static const StorageType minInclusive = 0;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitDownwards;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeNonPositiveInteger>
+ {
+ private:
+ friend class DerivedInteger<TypeNonPositiveInteger>;
+ typedef xsInteger StorageType;
+ typedef StorageType TemporaryStorageType;
+ static const StorageType maxInclusive = 0;
+ static const StorageType minInclusive = IgnorableSignedValue;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitUpwards;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypePositiveInteger>
+ {
+ private:
+ friend class DerivedInteger<TypePositiveInteger>;
+ typedef xsInteger StorageType;
+ typedef StorageType TemporaryStorageType;
+ static const StorageType maxInclusive = IgnorableSignedValue;
+ static const StorageType minInclusive = 1;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitDownwards;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeShort>
+ {
+ private:
+ friend class DerivedInteger<TypeShort>;
+ typedef qint16 StorageType;
+ typedef xsInteger TemporaryStorageType;
+ static const StorageType maxInclusive = 32767;
+ static const StorageType minInclusive = -32768;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeUnsignedByte>
+ {
+ private:
+ friend class DerivedInteger<TypeUnsignedByte>;
+ typedef quint8 StorageType;
+ typedef qint64 TemporaryStorageType;
+ static const StorageType maxInclusive = 255;
+ static const StorageType minInclusive = 0;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeUnsignedInt>
+ {
+ private:
+ friend class DerivedInteger<TypeUnsignedInt>;
+ typedef quint32 StorageType;
+ typedef qint64 TemporaryStorageType;
+ static const StorageType maxInclusive = Q_UINT64_C(4294967295);
+ static const StorageType minInclusive = 0;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeUnsignedLong>
+ {
+ private:
+ friend class DerivedInteger<TypeUnsignedLong>;
+ typedef quint64 StorageType;
+ typedef StorageType TemporaryStorageType;
+ static const StorageType maxInclusive = Q_UINT64_C(18446744073709551615);
+ static const StorageType minInclusive = 0;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ template<>
+ class DerivedIntegerDetails<TypeUnsignedShort>
+ {
+ private:
+ friend class DerivedInteger<TypeUnsignedShort>;
+ typedef quint16 StorageType;
+ typedef qint64 TemporaryStorageType;
+ static const StorageType maxInclusive = 65535;
+ static const StorageType minInclusive = 0;
+ static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth;
+
+ /**
+ * Disable the default constructor.
+ */
+ DerivedIntegerDetails() {}
+
+ Q_DISABLE_COPY(DerivedIntegerDetails)
+ };
+
+ /**
+ * @short Represents instances of derived @c xs:integer types, such as @c
+ * xs:byte.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ template<TypeOfDerivedInteger DerivedType>
+ class DerivedInteger : public Numeric
+ {
+ private:
+ typedef typename DerivedIntegerDetails<DerivedType>::StorageType StorageType;
+ typedef typename DerivedIntegerDetails<DerivedType>::TemporaryStorageType TemporaryStorageType;
+
+ static const StorageType maxInclusive = DerivedIntegerDetails<DerivedType>::maxInclusive;
+ static const StorageType minInclusive = DerivedIntegerDetails<DerivedType>::minInclusive;
+ static const DerivedIntegerLimitsUsage limitsUsage = DerivedIntegerDetails<DerivedType>::limitsUsage;
+
+ const StorageType m_value;
+
+ inline DerivedInteger(const StorageType num) : m_value(num)
+ {
+ }
+
+ /**
+ * By refactoring out the simple comparison below into a template
+ * function, we avoid the warning "warning: comparison of unsigned expression < 0 is always false" with gcc
+ * when the class is instantiated with TypeUnsignedLong. The warning is
+ * a false positive since we check wehther LimitUpwards is set before
+ * instantiating.
+ *
+ * This template function exists for no other reason. */
+ template<typename A, typename B>
+ static bool lessThan(const A &a, const B &b)
+ {
+ return a < b;
+ }
+
+ /**
+ * This function exists for the same reason that lessThan() do.
+ */
+ template<typename A, typename B>
+ static bool largerOrEqual(const A &a, const B &b)
+ {
+ return qint64(a) >= b;
+ }
+
+ public:
+
+ static ItemType::Ptr itemType()
+ {
+ switch(DerivedType)
+ {
+ case TypeByte: return BuiltinTypes::xsByte;
+ case TypeInt: return BuiltinTypes::xsInt;
+ case TypeLong: return BuiltinTypes::xsLong;
+ case TypeNegativeInteger: return BuiltinTypes::xsNegativeInteger;
+ case TypeNonNegativeInteger: return BuiltinTypes::xsNonNegativeInteger;
+ case TypeNonPositiveInteger: return BuiltinTypes::xsNonPositiveInteger;
+ case TypePositiveInteger: return BuiltinTypes::xsPositiveInteger;
+ case TypeShort: return BuiltinTypes::xsShort;
+ case TypeUnsignedByte: return BuiltinTypes::xsUnsignedByte;
+ case TypeUnsignedInt: return BuiltinTypes::xsUnsignedInt;
+ case TypeUnsignedLong: return BuiltinTypes::xsUnsignedLong;
+ case TypeUnsignedShort: return BuiltinTypes::xsUnsignedShort;
+ }
+
+ Q_ASSERT(false);
+ return ItemType::Ptr();
+ }
+
+ static AtomicValue::Ptr fromValue(const NamePool::Ptr &np, const TemporaryStorageType num)
+ {
+ /* If we use minInclusive when calling lessThan(), we for some
+ * reason get a linker error with GCC. Using this temporary
+ * variable solves it. */
+ const StorageType minimum = minInclusive;
+
+ if((limitsUsage & LimitUpwards) &&
+ num > maxInclusive)
+ {
+ return ValidationError::createError(QtXmlPatterns::tr(
+ "Value %1 of type %2 exceeds maximum (%3).")
+ .arg(QPatternist::formatData(static_cast<xsInteger>(num)))
+ .arg(formatType(np, itemType()))
+ .arg(QPatternist::formatData(static_cast<xsInteger>(maxInclusive))));
+ }
+ else if((limitsUsage & LimitDownwards) &&
+ lessThan(num, minimum))
+ {
+ return ValidationError::createError(QtXmlPatterns::tr(
+ "Value %1 of type %2 is below minimum (%3).")
+ .arg(QPatternist::formatData(static_cast<xsInteger>(num)))
+ .arg(formatType(np, itemType()))
+ .arg(QPatternist::formatData(static_cast<xsInteger>(minInclusive))));
+ }
+ else
+ return AtomicValue::Ptr(new DerivedInteger(num));
+ }
+
+ static AtomicValue::Ptr fromValueUnchecked(const TemporaryStorageType num)
+ {
+ return AtomicValue::Ptr(new DerivedInteger(num));
+ }
+
+ /**
+ * Constructs an instance from the lexical
+ * representation @p strNumeric.
+ */
+ static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &strNumeric)
+ {
+ bool conversionOk = false;
+ TemporaryStorageType num;
+
+ /* Depending on the type, we need to call different conversion
+ * functions on QString. */
+ switch(DerivedType)
+ {
+ case TypeUnsignedLong:
+ {
+ /* Qt decides to flag '-' as invalid, so remove it before. */
+ if(strNumeric.contains(QLatin1Char('-')))
+ {
+ num = QString(strNumeric).remove(QLatin1Char('-')).toULongLong(&conversionOk);
+
+ if(num != 0)
+ conversionOk = false;
+ }
+ else
+ num = strNumeric.toULongLong(&conversionOk);
+
+ break;
+ }
+ default:
+ {
+ num = strNumeric.toLongLong(&conversionOk);
+ break;
+ }
+ }
+
+ if(conversionOk)
+ return fromValue(np, num);
+ else
+ return ValidationError::createError();
+ }
+
+ inline StorageType storedValue() const
+ {
+ return m_value;
+ }
+
+ /**
+ * Determines the Effective %Boolean Value of this number.
+ *
+ * @returns @c false if the number is 0, otherwise @c true.
+ */
+ bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const
+ {
+ return m_value != 0;
+ }
+
+ virtual QString stringValue() const
+ {
+ return QString::number(m_value);
+ }
+
+ virtual ItemType::Ptr type() const
+ {
+ return itemType();
+ }
+
+ virtual xsDouble toDouble() const
+ {
+ return static_cast<xsDouble>(m_value);
+ }
+
+ virtual xsInteger toInteger() const
+ {
+ return m_value;
+ }
+
+ virtual xsFloat toFloat() const
+ {
+ return static_cast<xsFloat>(m_value);
+ }
+
+ virtual xsDecimal toDecimal() const
+ {
+ return static_cast<xsDecimal>(m_value);
+ }
+
+ virtual Numeric::Ptr round() const
+ {
+ /* xs:integerS never have a mantissa. */
+ return Numeric::Ptr(static_cast<Numeric *>(const_cast<AtomicValue *>(Integer::fromValue(m_value).asAtomicValue())));
+ }
+
+ virtual Numeric::Ptr roundHalfToEven(const xsInteger) const
+ {
+ return Numeric::Ptr(static_cast<Numeric *>(const_cast<AtomicValue *>(Integer::fromValue(m_value).asAtomicValue())));
+ }
+
+ virtual Numeric::Ptr floor() const
+ {
+ return Numeric::Ptr(static_cast<Numeric *>(const_cast<AtomicValue *>(Integer::fromValue(m_value).asAtomicValue())));
+ }
+
+ virtual Numeric::Ptr ceiling() const
+ {
+ return Numeric::Ptr(static_cast<Numeric *>(const_cast<AtomicValue *>(Integer::fromValue(m_value).asAtomicValue())));
+ }
+
+ virtual Numeric::Ptr abs() const
+ {
+ /* We unconditionally create an Integer even if we're a positive
+ * value, because one part of this is the type change to
+ * xs:integer.
+ *
+ * We've manually inlined qAbs() and invoke xsInteger's
+ * constructor. The reason being that we other gets truncation down
+ * to StorageType. See for instance XQTS test case absint1args-1. */
+ return Numeric::Ptr(static_cast<Numeric *>(const_cast<AtomicValue *>(Integer::fromValue(largerOrEqual(m_value, 0) ? xsInteger(m_value) : -xsInteger(m_value)).asAtomicValue())));
+ }
+
+ /**
+ * @returns always @c false, @c xs:DerivedInteger doesn't have
+ * not-a-number in its value space.
+ */
+ virtual bool isNaN() const
+ {
+ return false;
+ }
+
+ /**
+ * @returns always @c false, @c xs:DerivedInteger doesn't have
+ * infinity in its value space.
+ */
+ virtual bool isInf() const
+ {
+ return false;
+ }
+
+ virtual Item toNegated() const
+ {
+ return Integer::fromValue(-xsInteger(m_value));
+ }
+
+ virtual bool isSigned() const
+ {
+ switch(DerivedType)
+ {
+ /* Fallthrough all these. */
+ case TypeByte:
+ case TypeInt:
+ case TypeLong:
+ case TypeNegativeInteger:
+ case TypeNonNegativeInteger:
+ case TypeNonPositiveInteger:
+ case TypePositiveInteger:
+ case TypeShort:
+ return true;
+ /* Fallthrough all these. */
+ case TypeUnsignedByte:
+ case TypeUnsignedInt:
+ case TypeUnsignedLong:
+ case TypeUnsignedShort:
+ return false;
+ }
+ return false;
+ }
+
+ virtual qulonglong toUnsignedInteger() const
+ {
+ switch(DerivedType)
+ {
+ /* Fallthrough all these. */
+ case TypeByte:
+ case TypeInt:
+ case TypeLong:
+ case TypeNegativeInteger:
+ case TypeNonNegativeInteger:
+ case TypeNonPositiveInteger:
+ case TypePositiveInteger:
+ case TypeShort:
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function, see Numeric::toUnsignedInteger().");
+ /* Fallthrough all these. */
+ case TypeUnsignedByte:
+ case TypeUnsignedInt:
+ case TypeUnsignedLong:
+ case TypeUnsignedShort:
+ return m_value;
+ }
+ return 0;
+ }
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qderivedstring_p.h b/src/xmlpatterns/data/qderivedstring_p.h
new file mode 100644
index 0000000..9142b87
--- /dev/null
+++ b/src/xmlpatterns/data/qderivedstring_p.h
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DerivedString_H
+#define Patternist_DerivedString_H
+
+#include <QRegExp>
+
+#include "private/qxmlutils_p.h"
+#include "qbuiltintypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvalidationerror_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents instances of derived @c xs:string types, such as @c
+ * xs:normalizedString.
+ *
+ * Whitespace is a significant part for creating values from the lexical
+ * space. Of course the specification is tricky here. Here's some pointers:
+ *
+ * - From <a href="4.3.6.1 The whiteSpace Schema Component">XML Schema Part 2: Datatypes
+ * Second Edition, 4.3.6 whiteSpace</a>:
+ * "For all atomic datatypes other than string (and types
+ * derived by restriction from it) the value of whiteSpace is
+ * collapse and cannot be changed by a schema author; for string the
+ * value of whiteSpace is preserve; for any type derived by
+ * restriction from string the value of whiteSpace can be any of the
+ * three legal values."
+ * - From <a href="http://www.w3.org/TR/xmlschema-1/#d0e1654">XML Schema Part 1: Structures
+ * Second Edition, 3.1.4 White Space Normalization during Validation</a>:
+ * "[Definition:] The normalized value of an element or attribute
+ * information item is an initial value whose white space, if any,
+ * has been normalized according to the value of the whiteSpace facet of
+ * the simple type definition used in its validation."
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo Documentation is missing
+ */
+ template<TypeOfDerivedString DerivedType>
+ class DerivedString : public AtomicValue
+ {
+ private:
+ static inline ItemType::Ptr itemType()
+ {
+ switch(DerivedType)
+ {
+ case TypeNormalizedString: return BuiltinTypes::xsNormalizedString;
+ case TypeToken: return BuiltinTypes::xsToken;
+ case TypeLanguage: return BuiltinTypes::xsLanguage;
+ case TypeNMTOKEN: return BuiltinTypes::xsNMTOKEN;
+ case TypeName: return BuiltinTypes::xsName;
+ case TypeNCName: return BuiltinTypes::xsNCName;
+ case TypeID: return BuiltinTypes::xsID;
+ case TypeIDREF: return BuiltinTypes::xsIDREF;
+ case TypeENTITY: return BuiltinTypes::xsENTITY;
+ case TypeString: return BuiltinTypes::xsString;
+ }
+
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This line is not supposed to be reached.");
+ return ItemType::Ptr();
+ }
+
+ const QString m_value;
+
+ inline DerivedString(const QString &value) : m_value(value)
+ {
+ }
+
+ /**
+ * @short This is an incomplete test for whether @p ch conforms to
+ * the XML 1.0 NameChar production.
+ */
+ static inline bool isNameChar(const QChar &ch)
+ {
+ return ch.isLetter() ||
+ ch.isDigit() ||
+ ch == QLatin1Char('.') ||
+ ch == QLatin1Char('-') ||
+ ch == QLatin1Char('_') ||
+ ch == QLatin1Char(':');
+ }
+
+ /**
+ * @returns @c true if @p input is a valid @c xs:Name.
+ * @see <a href="http://www.w3.org/TR/REC-xml/#NT-Name">Extensible
+ * Markup Language (XML) 1.0 (Fourth Edition), [5] Name</a>
+ */
+ static inline bool isValidName(const QString &input)
+ {
+ if(input.isEmpty())
+ return false;
+
+ const QChar first(input.at(0));
+
+ if(first.isLetter() ||
+ first == QLatin1Char('_') ||
+ first == QLatin1Char(':'))
+ {
+ const int len = input.length();
+
+ if(len == 1)
+ return true;
+
+ /* Since we've checked the first character above, we start at
+ * position 1. */
+ for(int i = 1; i < len; ++i)
+ {
+ if(!isNameChar(input.at(i)))
+ return false;
+ }
+
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /**
+ * @returns @c true if @p input conforms to the XML 1.0 @c Nmtoken product.
+ *
+ * @see <a
+ * href="http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Nmtoken">Extensible
+ * Markup Language (XML) 1.0 (Second Edition), [7] Nmtoken</a>
+ */
+ static inline bool isValidNMTOKEN(const QString &input)
+ {
+ const int len = input.length();
+
+ if(len == 0)
+ return false;
+
+ for(int i = 0; i < len; ++i)
+ {
+ if(!isNameChar(input.at(i)))
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @short Performs attribute value normalization as if @p input was not
+ * from a @c CDATA section.
+ *
+ * Each whitespace character in @p input that's not a space, such as tab
+ * or new line character, is replaced with a space. This algorithm
+ * differs from QString::simplified() in that it doesn't collapse
+ * subsequent whitespace characters to a single one, or remove trailing
+ * and leading space.
+ *
+ * @see <a href="http://www.w3.org/TR/REC-xml/#AVNormalize">Extensible
+ * Markup Language (XML) 1.0 (Second Edition), 3.3.3 [E70]Attribute-Value Normalization</a>
+ */
+ static QString attributeNormalize(const QString &input)
+ {
+ QString retval(input);
+ const int len = retval.length();
+ const QLatin1Char space(' ');
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QChar ati(retval.at(i));
+
+ if(ati.isSpace() && ati != space)
+ retval[i] = space;
+ }
+
+ return retval;
+ }
+
+ static AtomicValue::Ptr error(const NamePool::Ptr &np, const QString &invalidValue)
+ {
+ return ValidationError::createError(QString::fromLatin1("%1 is not a valid value for "
+ "type %2.").arg(formatData(invalidValue))
+ .arg(formatType(np, itemType())));
+ }
+
+ public:
+
+ /**
+ * @note This function doesn't perform any cleanup/normalizaiton of @p
+ * value. @p value must be a canonical value space of the type.
+ *
+ * If you want cleanup to be performed and/or the lexical space
+ * checked, use fromLexical().
+ */
+ static AtomicValue::Ptr fromValue(const QString &value)
+ {
+ return AtomicValue::Ptr(new DerivedString(value));
+ }
+
+ /**
+ * Constructs an instance from the lexical
+ * representation @p lexical.
+ */
+ static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &lexical)
+ {
+ switch(DerivedType)
+ {
+ case TypeString:
+ return AtomicValue::Ptr(new DerivedString(lexical));
+ case TypeNormalizedString:
+ return AtomicValue::Ptr(new DerivedString(attributeNormalize(lexical)));
+ case TypeToken:
+ return AtomicValue::Ptr(new DerivedString(lexical.simplified()));
+ case TypeLanguage:
+ {
+ const QString simplified(lexical.trimmed());
+
+ const QRegExp validate(QLatin1String("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"));
+ Q_ASSERT(validate.isValid());
+
+ if(validate.exactMatch(simplified))
+ return AtomicValue::Ptr(new DerivedString(lexical.simplified()));
+ else
+ return error(np, simplified);
+ }
+ case TypeNMTOKEN:
+ {
+ const QString trimmed(lexical.trimmed());
+
+ if(isValidNMTOKEN(trimmed))
+ return AtomicValue::Ptr(new DerivedString(trimmed));
+ else
+ return error(np, trimmed);
+ }
+ case TypeName:
+ {
+ const QString simplified(lexical.simplified());
+
+ if(isValidName(simplified))
+ return AtomicValue::Ptr(new DerivedString(simplified));
+ else
+ return error(np, simplified);
+ }
+ case TypeID:
+ /* Fallthrough. */
+ case TypeIDREF:
+ /* Fallthrough. */
+ case TypeENTITY:
+ /* Fallthrough. */
+ case TypeNCName:
+ {
+ /* We treat xs:ID, xs:ENTITY, xs:IDREF and xs:NCName in the exact same
+ * way, except for the type annotation.
+ *
+ * We use trimmed() instead of simplified() because it's
+ * faster and whitespace isn't allowed between
+ * non-whitespace characters anyway, for these types. */
+ const QString trimmed(lexical.trimmed());
+
+ if(QXmlUtils::isNCName(trimmed))
+ return AtomicValue::Ptr(new DerivedString(trimmed));
+ else
+ return error(np, trimmed);
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This line is not supposed to be reached.");
+ return AtomicValue::Ptr();
+ }
+ }
+ }
+
+ virtual QString stringValue() const
+ {
+ return m_value;
+ }
+
+ virtual bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const
+ {
+ return m_value.length() > 0;
+ }
+
+ virtual ItemType::Ptr type() const
+ {
+ return itemType();
+ }
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qduration.cpp b/src/xmlpatterns/data/qduration.cpp
new file mode 100644
index 0000000..6849a8b
--- /dev/null
+++ b/src/xmlpatterns/data/qduration.cpp
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractdatetime_p.h"
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+
+#include "qduration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Duration::Duration(const bool isPositiveP,
+ const YearProperty yearsP,
+ const MonthProperty monthsP,
+ const DayCountProperty daysP,
+ const HourProperty hoursP,
+ const MinuteProperty mins,
+ const SecondProperty secs,
+ const MSecondProperty msecs) : AbstractDuration(isPositiveP),
+ m_years(yearsP),
+ m_months(monthsP),
+ m_days(daysP),
+ m_hours(hoursP),
+ m_minutes(mins),
+ m_seconds(secs),
+ m_mseconds(msecs)
+{
+}
+
+Duration::Ptr Duration::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable(
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(-)?" /* Any minus sign. */
+ "P" /* Delimiter. */
+ "(?:(\\d+)Y)?" /* Year part. */
+ "(?:(\\d+)M)?" /* Month part. */
+ "(?:(\\d+)D)?" /* Day part. */
+ "(?:" /* Here starts the optional time part. */
+ "(T)" /* SchemaTime delimiter. */
+ "(?:(\\d+)H)?" /* Hour part. */
+ "(?:(\\d+)M)?" /* Minute part. */
+ "(?:(\\d+)(?:\\.(\\d+))?S)?" /* Seconds & milli seconds. */
+ ")?" /* End of optional time part. */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*yearP*/ 2,
+ /*monthP*/ 3,
+ /*dayP*/ 4,
+ /*tDelimiterP*/ 5,
+ /*hourP*/ 6,
+ /*minutesP*/ 7,
+ /*secondsP*/ 8,
+ /*msecondsP*/ 9);
+
+ YearProperty years = 0;
+ MonthProperty months = 0;
+ DayCountProperty days = 0;
+ HourProperty hours = 0;
+ MinuteProperty minutes = 0;
+ SecondProperty sec = 0;
+ MSecondProperty msec = 0;
+ bool isPos;
+
+ const AtomicValue::Ptr err(create(captureTable, lexical, &isPos, &years, &months,
+ &days, &hours, &minutes, &sec, &msec));
+
+ return err ? err : Duration::Ptr(new Duration(isPos, years, months, days, hours,
+ minutes, sec, msec));
+}
+
+Duration::Ptr Duration::fromComponents(const bool isPositive,
+ const YearProperty years,
+ const MonthProperty months,
+ const DayCountProperty days,
+ const HourProperty hours,
+ const MinuteProperty minutes,
+ const SecondProperty seconds,
+ const MSecondProperty mseconds)
+{
+ return Duration::Ptr(new Duration(isPositive, years, months, days,
+ hours, minutes, seconds, mseconds));
+}
+
+AbstractDuration::Value Duration::value() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Calling Duration::value() makes no sense");
+ return 0;
+}
+
+Item Duration::fromValue(const Value) const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Calling Duration::fromValue() makes no sense");
+ return Item();
+}
+
+QString Duration::stringValue() const
+{
+ QString retval;
+
+ if(!m_isPositive)
+ retval.append(QLatin1Char('-'));
+
+ retval.append(QLatin1Char('P'));
+
+ if(m_years)
+ {
+ retval.append(QString::number(m_years));
+ retval.append(QLatin1Char('Y'));
+ }
+
+ if(m_months)
+ {
+ retval.append(QString::number(m_months));
+ retval.append(QLatin1Char('M'));
+ }
+
+ if(m_days)
+ {
+ retval.append(QString::number(m_days));
+ retval.append(QLatin1Char('D'));
+ }
+
+ if(!m_hours && !m_minutes && !m_seconds && !m_seconds)
+ {
+ if(!m_years && !m_months && !m_days)
+ return QLatin1String("PT0S");
+ else
+ return retval;
+ }
+
+ retval.append(QLatin1Char('T'));
+
+ if(m_hours)
+ {
+ retval.append(QString::number(m_hours));
+ retval.append(QLatin1Char('H'));
+ }
+
+ if(m_minutes)
+ {
+ retval.append(QString::number(m_minutes));
+ retval.append(QLatin1Char('M'));
+ }
+
+ if(m_seconds || m_seconds)
+ {
+ retval.append(QString::number(m_seconds));
+
+ if(m_mseconds)
+ retval.append(serializeMSeconds(m_mseconds));
+
+ retval.append(QLatin1Char('S'));
+ }
+ else if(!m_years && !m_months && !m_days && !m_hours && !m_minutes)
+ retval.append(QLatin1String("0S"));
+
+ return retval;
+}
+
+YearProperty Duration::years() const
+{
+ return m_years;
+}
+
+MonthProperty Duration::months() const
+{
+ return m_months;
+}
+
+DayCountProperty Duration::days() const
+{
+ return m_days;
+}
+
+HourProperty Duration::hours() const
+{
+ return m_hours;
+}
+
+MinuteProperty Duration::minutes() const
+{
+ return m_minutes;
+}
+
+SecondProperty Duration::seconds() const
+{
+ return m_seconds;
+}
+
+MSecondProperty Duration::mseconds() const
+{
+ return m_mseconds;
+}
+
+ItemType::Ptr Duration::type() const
+{
+ return BuiltinTypes::xsDuration;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qduration_p.h b/src/xmlpatterns/data/qduration_p.h
new file mode 100644
index 0000000..de84a1a
--- /dev/null
+++ b/src/xmlpatterns/data/qduration_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Duration_H
+#define Patternist_Duration_H
+
+#include "qabstractduration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:duration type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class Duration : public AbstractDuration
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static Duration::Ptr fromLexical(const QString &string);
+ static Duration::Ptr fromComponents(const bool isPositive,
+ const YearProperty years,
+ const MonthProperty months,
+ const DayCountProperty days,
+ const HourProperty hours,
+ const MinuteProperty minutes,
+ const SecondProperty seconds,
+ const MSecondProperty mseconds);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+
+ /**
+ * Always results in an assert crash. Calling this function makes no
+ * sense due to that the value space of xs:duration is not well defined.
+ */
+ virtual Value value() const;
+
+ /**
+ * Always results in an assert crash. Calling this function makes no
+ * sense due to that the value space of xs:duration is not well defined.
+ */
+ virtual Item fromValue(const Value val) const;
+
+ virtual YearProperty years() const;
+ virtual MonthProperty months() const;
+ virtual DayCountProperty days() const;
+ virtual HourProperty hours() const;
+ virtual MinuteProperty minutes() const;
+ virtual SecondProperty seconds() const;
+ virtual MSecondProperty mseconds() const;
+
+ protected:
+ friend class CommonValues;
+
+ Duration(const bool isPositive,
+ const YearProperty years,
+ const MonthProperty months,
+ const DayCountProperty days,
+ const HourProperty hours,
+ const MinuteProperty minutes,
+ const SecondProperty seconds,
+ const MSecondProperty mseconds);
+ private:
+ const YearProperty m_years;
+ const MonthProperty m_months;
+ const DayCountProperty m_days;
+ const HourProperty m_hours;
+ const MinuteProperty m_minutes;
+ const SecondProperty m_seconds;
+ const MSecondProperty m_mseconds;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qgday.cpp b/src/xmlpatterns/data/qgday.cpp
new file mode 100644
index 0000000..c11acbd
--- /dev/null
+++ b/src/xmlpatterns/data/qgday.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qgday_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GDay::GDay(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+GDay::Ptr GDay::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "---" /* Delimiter. */
+ "(\\d{2})" /* The day part, "03". */
+ "(?:(?:(\\+|-))(\\d{2}):(\\d{2})|(Z))?" /* Timezone, "+08:24". */
+ "\\s*$" /* Any whitespace at the end. */))),
+ /*zoneOffsetSignP*/ 2,
+ /*zoneOffsetHourP*/ 3,
+ /*zoneOffsetMinuteP*/ 4,
+ /*zoneOffsetUTCSymbolP*/ 5,
+ /*yearP*/ -1,
+ /*monthP*/ -1,
+ /*dayP*/ 1);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : GDay::Ptr(new GDay(retval));
+}
+
+GDay::Ptr GDay::fromDateTime(const QDateTime &dt)
+{
+ QDateTime result(QDate(DefaultYear, DefaultMonth, dt.date().day()));
+ copyTimeSpec(dt, result);
+
+ return GDay::Ptr(new GDay(result));
+}
+
+QString GDay::stringValue() const
+{
+ return m_dateTime.toString(QLatin1String("---dd")) + zoneOffsetToString();
+}
+
+ItemType::Ptr GDay::type() const
+{
+ return BuiltinTypes::xsGDay;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qgday_p.h b/src/xmlpatterns/data/qgday_p.h
new file mode 100644
index 0000000..b958769
--- /dev/null
+++ b/src/xmlpatterns/data/qgday_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GDay_H
+#define Patternist_GDay_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:gDay type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class GDay : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static GDay::Ptr fromLexical(const QString &string);
+ static GDay::Ptr fromDateTime(const QDateTime &dt);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+
+ protected:
+ friend class CommonValues;
+
+ GDay(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qgmonth.cpp b/src/xmlpatterns/data/qgmonth.cpp
new file mode 100644
index 0000000..1651735
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonth.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qgmonth_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GMonth::GMonth(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+GMonth::Ptr GMonth::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "--" /* Delimier. */
+ "(\\d{2})" /* The month part, "03". */
+ "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* Timezone, "+08:24". */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*zoneOffsetSignP*/ 2,
+ /*zoneOffsetHourP*/ 3,
+ /*zoneOffsetMinuteP*/ 4,
+ /*zoneOffsetUTCSymbolP*/ 5,
+ /*yearP*/ -1,
+ /*monthP*/ 1);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : GMonth::Ptr(new GMonth(retval));
+}
+
+GMonth::Ptr GMonth::fromDateTime(const QDateTime &dt)
+{
+ QDateTime result(QDate(DefaultYear, dt.date().month(), DefaultDay));
+ copyTimeSpec(dt, result);
+
+ return GMonth::Ptr(new GMonth(result));
+}
+
+QString GMonth::stringValue() const
+{
+ return m_dateTime.toString(QLatin1String("--MM")) + zoneOffsetToString();
+}
+
+ItemType::Ptr GMonth::type() const
+{
+ return BuiltinTypes::xsGMonth;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qgmonth_p.h b/src/xmlpatterns/data/qgmonth_p.h
new file mode 100644
index 0000000..2ff766a
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonth_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GMonth_H
+#define Patternist_GMonth_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:gMonth type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class GMonth : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static GMonth::Ptr fromLexical(const QString &string);
+ static GMonth::Ptr fromDateTime(const QDateTime &dt);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+
+ protected:
+ friend class CommonValues;
+
+ GMonth(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qgmonthday.cpp b/src/xmlpatterns/data/qgmonthday.cpp
new file mode 100644
index 0000000..fe1210d
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonthday.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qgmonthday_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GMonthDay::GMonthDay(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+GMonthDay::Ptr GMonthDay::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "--" /* Delimiter. */
+ "(\\d{2})" /* The month part. */
+ "-" /* Delimiter. */
+ "(\\d{2})" /* The day part. */
+ "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*zoneOffsetSignP*/ 3,
+ /*zoneOffsetHourP*/ 4,
+ /*zoneOffsetMinuteP*/ 5,
+ /*zoneOffsetUTCSymbolP*/ 6,
+ /*yearP*/ -1,
+ /*monthP*/ 1,
+ /*dayP*/ 2);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : GMonthDay::Ptr(new GMonthDay(retval));
+}
+
+GMonthDay::Ptr GMonthDay::fromDateTime(const QDateTime &dt)
+{
+ QDateTime result(QDate(DefaultYear, dt.date().month(), dt.date().day()));
+ copyTimeSpec(dt, result);
+
+ return GMonthDay::Ptr(new GMonthDay(result));
+}
+
+QString GMonthDay::stringValue() const
+{
+ return m_dateTime.toString(QLatin1String("--MM-dd")) + zoneOffsetToString();
+}
+
+ItemType::Ptr GMonthDay::type() const
+{
+ return BuiltinTypes::xsGMonthDay;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qgmonthday_p.h b/src/xmlpatterns/data/qgmonthday_p.h
new file mode 100644
index 0000000..a979646
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonthday_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GMonthDay_H
+#define Patternist_GMonthDay_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:gYearMonth type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class GMonthDay : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static GMonthDay::Ptr fromLexical(const QString &string);
+ static GMonthDay::Ptr fromDateTime(const QDateTime &dt);
+
+ virtual ItemType::Ptr type() const;
+
+ virtual QString stringValue() const;
+
+ protected:
+ friend class CommonValues;
+
+ GMonthDay(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qgyear.cpp b/src/xmlpatterns/data/qgyear.cpp
new file mode 100644
index 0000000..488cd5e
--- /dev/null
+++ b/src/xmlpatterns/data/qgyear.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qgyear_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GYear::GYear(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+GYear::Ptr GYear::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(-?)" /* Any preceding minus. */
+ "(-?\\d{4,})" /* The year part, "1999". */
+ "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*zoneOffsetSignP*/ 3,
+ /*zoneOffsetHourP*/ 4,
+ /*zoneOffsetMinuteP*/ 5,
+ /*zoneOffsetUTCSymbolP*/ 6,
+ /*yearP*/ 2,
+ /*monthP*/ -1,
+ /*dayP*/ -1,
+ /*hourP*/ -1,
+ /*minutesP*/ -1,
+ /*secondsP*/ -1,
+ /*msecondsP*/ -1,
+ /*yearSign*/ 1);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : GYear::Ptr(new GYear(retval));
+}
+
+GYear::Ptr GYear::fromDateTime(const QDateTime &dt)
+{
+ QDateTime result(QDate(dt.date().year(), DefaultMonth, DefaultDay));
+ copyTimeSpec(dt, result);
+
+ return GYear::Ptr(new GYear(result));
+}
+
+QString GYear::stringValue() const
+{
+ return m_dateTime.toString(QLatin1String("yyyy")) + zoneOffsetToString();
+}
+
+ItemType::Ptr GYear::type() const
+{
+ return BuiltinTypes::xsGYear;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qgyear_p.h b/src/xmlpatterns/data/qgyear_p.h
new file mode 100644
index 0000000..a02f0c2
--- /dev/null
+++ b/src/xmlpatterns/data/qgyear_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GYear_H
+#define Patternist_GYear_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:gYear type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class GYear : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static GYear::Ptr fromLexical(const QString &string);
+ static GYear::Ptr fromDateTime(const QDateTime &dt);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+
+ protected:
+ friend class CommonValues;
+
+ GYear(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qgyearmonth.cpp b/src/xmlpatterns/data/qgyearmonth.cpp
new file mode 100644
index 0000000..665059b
--- /dev/null
+++ b/src/xmlpatterns/data/qgyearmonth.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qgyearmonth_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GYearMonth::GYearMonth(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+GYearMonth::Ptr GYearMonth::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(-?)" /* Any preceding minus. */
+ "(\\d{4,})" /* The year part. */
+ "-" /* Delimiter. */
+ "(\\d{2})" /* The month part. */
+ "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*zoneOffsetSignP*/ 4,
+ /*zoneOffsetHourP*/ 5,
+ /*zoneOffsetMinuteP*/ 6,
+ /*zoneOffsetUTCSymbolP*/ 7,
+ /*yearP*/ 2,
+ /*monthP*/ 3,
+ /*dayP*/ -1,
+ /*hourP*/ -1,
+ /*minutesP*/ -1,
+ /*secondsP*/ -1,
+ /*msecondsP*/ -1,
+ /*yearSign*/ 1);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : GYearMonth::Ptr(new GYearMonth(retval));
+}
+
+GYearMonth::Ptr GYearMonth::fromDateTime(const QDateTime &dt)
+{
+ QDateTime result(QDate(dt.date().year(), dt.date().month(), DefaultDay));
+ copyTimeSpec(dt, result);
+
+ return GYearMonth::Ptr(new GYearMonth(result));
+}
+
+QString GYearMonth::stringValue() const
+{
+ return m_dateTime.toString(QLatin1String("yyyy-MM")) + zoneOffsetToString();
+}
+
+ItemType::Ptr GYearMonth::type() const
+{
+ return BuiltinTypes::xsGYearMonth;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qgyearmonth_p.h b/src/xmlpatterns/data/qgyearmonth_p.h
new file mode 100644
index 0000000..6d74d8e
--- /dev/null
+++ b/src/xmlpatterns/data/qgyearmonth_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GYearMonth_H
+#define Patternist_GYearMonth_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:gYearMonth type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class GYearMonth : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static GYearMonth::Ptr fromLexical(const QString &string);
+ static GYearMonth::Ptr fromDateTime(const QDateTime &dt);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+
+ protected:
+ friend class CommonValues;
+
+ GYearMonth(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qhexbinary.cpp b/src/xmlpatterns/data/qhexbinary.cpp
new file mode 100644
index 0000000..c9360fe
--- /dev/null
+++ b/src/xmlpatterns/data/qhexbinary.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGlobal>
+
+#include "qbase64binary_p.h"
+#include "qbuiltintypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qhexbinary_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+HexBinary::HexBinary(const QByteArray &val) : Base64Binary(val)
+{
+}
+
+qint8 HexBinary::fromHex(const QChar &c)
+{
+ if(c.unicode() > 'f')
+ return -1;
+
+ const char *const range = "0123456789ABCDEFabcdef";
+
+ const char *const in = strchr(range, c.unicode());
+
+ if(!in)
+ return -1;
+
+ /* Pointer arithmetic. */
+ int digit = in - range;
+
+ if(digit > 15)
+ digit -= 6;
+
+ return digit;
+}
+
+AtomicValue::Ptr HexBinary::fromLexical(const NamePool::Ptr &np, const QString &str)
+{
+ const QString lexical(str.trimmed());
+ const int len = lexical.length();
+
+ if(len == 0)
+ return AtomicValue::Ptr(new HexBinary(QByteArray()));
+
+ if((len & 1) != 0)
+ {
+ /* Catch a common case. */
+ return ValidationError::createError(QtXmlPatterns::tr(
+ "A value of type %1 must contain an even number of "
+ "digits. The value %2 does not.")
+ .arg(formatType(np, BuiltinTypes::xsHexBinary),
+ formatData(QString::number(len))));
+ }
+
+ QByteArray val;
+ val.resize(len / 2);
+
+ for(int i = 0; i < len / 2; ++i)
+ {
+ qint8 p1 = fromHex(lexical[i * 2]);
+ qint8 p2 = fromHex(lexical[i * 2 + 1]);
+
+ if(p1 == -1 || p2 == -1)
+ {
+ const QString hex(QString::fromLatin1("%1%2").arg(lexical[i * 2], lexical[i * 2 + 1]));
+
+ return ValidationError::createError(QtXmlPatterns::tr(
+ "%1 is not valid as a value of type %2.")
+ .arg(formatData(hex),
+ formatType(np, BuiltinTypes::xsHexBinary)));
+ }
+
+ val[i] = static_cast<char>(p1 * 16 + p2);
+ }
+ Q_ASSERT(!val.isEmpty());
+
+ return AtomicValue::Ptr(new HexBinary(val));
+}
+
+HexBinary::Ptr HexBinary::fromValue(const QByteArray &data)
+{
+ return HexBinary::Ptr(new HexBinary(data));
+}
+
+QString HexBinary::stringValue() const
+{
+ static const char s_toHex[] = "0123456789ABCDEF";
+ const int len = m_value.count();
+ QString result;
+ result.reserve(len * 2);
+
+ for(int i = 0; i < len; ++i)
+ {
+ // This cast is significant.
+ const unsigned char val = static_cast<unsigned char>(m_value.at(i));
+ result += QLatin1Char(s_toHex[val >> 4]);
+ result += QLatin1Char(s_toHex[val & 0x0F]);
+ }
+
+ return result;
+}
+
+ItemType::Ptr HexBinary::type() const
+{
+ return BuiltinTypes::xsHexBinary;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qhexbinary_p.h b/src/xmlpatterns/data/qhexbinary_p.h
new file mode 100644
index 0000000..5dd1624
--- /dev/null
+++ b/src/xmlpatterns/data/qhexbinary_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_HexBinary_H
+#define Patternist_HexBinary_H
+
+#include "qbase64binary_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the value instance of the @c xs:hexBinary type.
+ *
+ * HexBinary inherits from Base64Binary for implementation reasons. The two
+ * classes are similar, and inheritance therefore save code.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo Documentation is missing
+ */
+ class HexBinary : public Base64Binary
+ {
+ public:
+ friend class CommonValues;
+
+ typedef AtomicValue::Ptr Ptr;
+
+ virtual QString stringValue() const;
+ virtual ItemType::Ptr type() const;
+
+ /**
+ * Creates a @c xs:hexBinary from the lexical representation @p value.
+ */
+ static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &value);
+
+ /**
+ * Creates an instance representing @p value.
+ */
+ static HexBinary::Ptr fromValue(const QByteArray &data);
+
+ protected:
+ HexBinary(const QByteArray &val);
+
+ private:
+ /**
+ * @short Returns -1 on invalid input.
+ */
+ static inline qint8 fromHex(const QChar &c);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qinteger.cpp b/src/xmlpatterns/data/qinteger.cpp
new file mode 100644
index 0000000..7fc6b3d
--- /dev/null
+++ b/src/xmlpatterns/data/qinteger.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qinteger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item Integer::fromValue(const xsInteger num)
+{
+ return toItem(Integer::Ptr(new Integer(num)));
+}
+
+AtomicValue::Ptr Integer::fromLexical(const QString &strNumeric)
+{
+ bool conversionOk = false;
+ const xsInteger num = strNumeric.toLongLong(&conversionOk);
+
+ if(conversionOk)
+ return AtomicValue::Ptr(new Integer(num));
+ else
+ return ValidationError::createError();
+}
+
+Integer::Integer(const xsInteger num) : m_value(num)
+{
+}
+
+bool Integer::evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const
+{
+ return m_value != 0;
+}
+
+QString Integer::stringValue() const
+{
+ return QString::number(m_value);
+}
+
+ItemType::Ptr Integer::type() const
+{
+ return BuiltinTypes::xsInteger;
+}
+
+xsDouble Integer::toDouble() const
+{
+ return static_cast<xsDouble>(m_value);
+}
+
+xsInteger Integer::toInteger() const
+{
+ return m_value;
+}
+
+xsFloat Integer::toFloat() const
+{
+ return static_cast<xsFloat>(m_value);
+}
+
+xsDecimal Integer::toDecimal() const
+{
+ return static_cast<xsDecimal>(m_value);
+}
+
+Numeric::Ptr Integer::round() const
+{
+ /* xs:integerS never has a mantissa. */
+ return Numeric::Ptr(const_cast<Integer *>(this));
+}
+
+Numeric::Ptr Integer::roundHalfToEven(const xsInteger /*scale*/) const
+{
+ return Numeric::Ptr(const_cast<Integer *>(this));
+}
+
+Numeric::Ptr Integer::floor() const
+{
+ return Numeric::Ptr(const_cast<Integer *>(this));
+}
+
+Numeric::Ptr Integer::ceiling() const
+{
+ return Numeric::Ptr(const_cast<Integer *>(this));
+}
+
+Numeric::Ptr Integer::abs() const
+{
+ /* No reason to allocate an Integer if we're already absolute. */
+ if(m_value < 0)
+ return Numeric::Ptr(new Integer(qAbs(m_value)));
+ else
+ return Numeric::Ptr(const_cast<Integer *>(this));
+}
+
+bool Integer::isNaN() const
+{
+ return false;
+}
+
+bool Integer::isInf() const
+{
+ return false;
+}
+
+Item Integer::toNegated() const
+{
+ return fromValue(-m_value);
+}
+
+bool Integer::isSigned() const
+{
+ return true;
+}
+
+qulonglong Integer::toUnsignedInteger() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function, see Numeric::toUnsignedInteger().");
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qinteger_p.h b/src/xmlpatterns/data/qinteger_p.h
new file mode 100644
index 0000000..20a5931
--- /dev/null
+++ b/src/xmlpatterns/data/qinteger_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Integer_H
+#define Patternist_Integer_H
+
+#include "qschemanumeric_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:integer type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo Documentation is missing
+ */
+ class Integer : public Numeric
+ {
+ public:
+
+ typedef Numeric::Ptr Ptr;
+
+ /**
+ * Constructs an instance from the lexical
+ * representation @p strNumeric.
+ *
+ * @todo Type error handling.
+ */
+ static AtomicValue::Ptr fromLexical(const QString &strNumeric);
+
+ static Item fromValue(const xsInteger num);
+
+ /**
+ * Determines the Effective %Boolean Value of this number.
+ *
+ * @returns @c false if the number is 0, otherwise @c true.
+ */
+ bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &) const;
+
+ virtual QString stringValue() const;
+
+ /**
+ * @returns always BuiltinTypes::xsInteger
+ */
+ virtual ItemType::Ptr type() const;
+
+ virtual xsDouble toDouble() const;
+ virtual xsInteger toInteger() const;
+ virtual xsFloat toFloat() const;
+ virtual xsDecimal toDecimal() const;
+
+ virtual Numeric::Ptr round() const;
+ virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const;
+ virtual Numeric::Ptr floor() const;
+ virtual Numeric::Ptr ceiling() const;
+ virtual Numeric::Ptr abs() const;
+ virtual qulonglong toUnsignedInteger() const;
+
+ /**
+ * @returns always @c false, @c xs:integer doesn't have
+ * not-a-number in its value space.
+ */
+ virtual bool isNaN() const;
+
+ /**
+ * @returns always @c false, @c xs:integer doesn't have
+ * infinity in its value space.
+ */
+ virtual bool isInf() const;
+ virtual Item toNegated() const;
+
+ /**
+ * @short Returns always @c true.
+ */
+ virtual bool isSigned() const;
+ protected:
+ Integer(const xsInteger num);
+
+ private:
+ const xsInteger m_value;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qitem.cpp b/src/xmlpatterns/data/qitem.cpp
new file mode 100644
index 0000000..4302fa8
--- /dev/null
+++ b/src/xmlpatterns/data/qitem.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item::Iterator::Ptr Item::sequencedTypedValue() const
+{
+ if(isAtomicValue())
+ return makeSingletonIterator(Item(atomicValue));
+ else
+ return asNode().sequencedTypedValue();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qitem_p.h b/src/xmlpatterns/data/qitem_p.h
new file mode 100644
index 0000000..8184b25
--- /dev/null
+++ b/src/xmlpatterns/data/qitem_p.h
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Item_H
+#define Patternist_Item_H
+
+#include <QtXmlPatterns/private/qcppcastinghelper_p.h>
+#include <QtXmlPatterns/private/qitemtype_p.h>
+#include <QtXmlPatterns/private/qsingletoniterator_p.h>
+#include <QtXmlPatterns/QAbstractXmlNodeModel>
+
+#include <QUrl>
+#include <QVariant>
+
+/**
+ * @file
+ * @short Due to strong interdependencies, this file contains the definitions for
+ * the classes Item, QXmlNodeModelIndex, QAbstractXmlNodeModel and AtomicValue. The implementations are
+ * in their respective source files.
+ */
+
+/**
+ * @class QSharedData
+ * @short Qt's base class for reference counting.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QList;
+template<typename T> class QVector;
+template<typename T> class QAbstractXmlForwardIterator;
+
+class QSourceLocation;
+class QAbstractXmlReceiver;
+
+namespace QPatternist
+{
+ class DynamicContext;
+ class Item;
+ class ItemType;
+ class QObjectNodeModel;
+ template<typename T> class EmptyIterator;
+ template<typename T, typename ListType> class ListIterator;
+
+ /**
+ * @short Base class for all classes representing atomic values.
+ *
+ * Instantiating AtomicValues sub classes from a value of somekind,
+ * for a certain type is done in three different ways:
+ *
+ * - The static factory fromLexical which available in most classes. This
+ * function attempts to create a value from a QString that is considered
+ * a lexical representation of the value. Thus, this function performs validation, takes
+ * care of whitespace facets, and everything else related to instantiating a value from
+ * a lexical representation.
+ * - The static factory function fromValue. This function exists for
+ * values where a C++ type exists which corresponds to the type's value space.
+ * - By using instances available in CommonValues. This is the preferred method
+ * since it uses existing singleton instances and thus saves memory. CommonValues
+ * should be used whenever possible, it can be thought as a collection of constant values.
+ *
+ * For types that does not distinguish the value space and lexical space, such as <tt>xs:string</tt>,
+ * only the fromValue() function exist, and fromLexical() is omitted.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicValue : public QSharedData
+ , public CppCastingHelper<AtomicValue>
+ {
+ public:
+ virtual ~AtomicValue();
+
+ /**
+ * A smart pointer wrapping AtomicValue instances.
+ */
+ typedef QExplicitlySharedDataPointer<AtomicValue> Ptr;
+
+ /**
+ * A list if smart pointers wrapping AtomicValue instances.
+ */
+ typedef QList<AtomicValue::Ptr> List;
+
+ /**
+ * Determines whether this atomic value has an error. This is used
+ * for implementing casting.
+ *
+ * @returns always @c false
+ */
+ virtual bool hasError() const;
+
+ /**
+ * Always fails by issuing the type error ReportContext::FORG0006. Sub-classes
+ * whose represented type do allow EBV to be extracted from, must thus
+ * re-implement this function.
+ */
+ virtual bool evaluateEBV(const QExplicitlySharedDataPointer<DynamicContext> &context) const;
+
+ virtual QString stringValue() const = 0;
+ virtual ItemType::Ptr type() const = 0;
+
+ /**
+ * Converts @p value to a QVariant.
+ */
+ static QVariant toQt(const AtomicValue *const value);
+
+ static inline QVariant toQt(const AtomicValue::Ptr &value)
+ {
+ return toQt(value.data());
+ }
+
+ static Item toXDM(const QVariant &value);
+
+ static ItemType::Ptr qtToXDMType(const QXmlItem &item);
+ protected:
+ inline AtomicValue()
+ {
+ }
+ };
+
+ /**
+ * @short Represents an item in the XPath 2.0 Data Model.
+ *
+ * There exists two types of items: nodes and atomic values.
+ *
+ * The XQuery 1.0 and XPath 2.0 Data Model and XML Path Language (XPath) 2.0 specification
+ * makes a very strong distinction between a sequence of items and an atomized sequence.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Item
+ {
+ friend class QT_PREPEND_NAMESPACE(QXmlItem);
+
+ public:
+ /**
+ * A smart pointer wrapping an Item instance.
+ */
+ typedef QAbstractXmlForwardIterator<Item> Iterator;
+
+ /**
+ * A list of Item instances, each wrapped in a smart pointer.
+ */
+ typedef QList<Item> List;
+
+ /**
+ * A vector of Item instances, each wrapped in a smart pointer.
+ */
+ typedef QVector<Item> Vector;
+
+ typedef QPatternist::SingletonIterator<Item> SingletonIterator;
+ typedef QPatternist::EmptyIterator<Item> EmptyIterator;
+
+ /**
+ * Default constructor.
+ */
+ inline Item()
+ {
+ /* Note that this function should be equal to reset(). */
+
+ /* This is the area which atomicValue uses. Becauase we want as()
+ * to return null on null-constructed objects, we initialize it. */
+ node.data = 0;
+
+ /* This signals that we're not an atomic value. */
+ node.model = 0;
+ }
+
+ inline Item(const QXmlNodeModelIndex &n) : node(n.m_storage)
+ {
+ }
+
+ inline Item(const Item &other) : node(other.node)
+ {
+ Q_ASSERT_X(sizeof(QXmlNodeModelIndex) >= sizeof(AtomicValue), Q_FUNC_INFO,
+ "Since we're only copying the node member, it must be the largest.");
+ if(isAtomicValue())
+ atomicValue->ref.ref();
+ }
+
+ inline Item(const AtomicValue::Ptr &a)
+ {
+ if(a)
+ {
+ atomicValue = a.data();
+ atomicValue->ref.ref();
+
+ /* Signal that we're housing an atomic value. */
+ node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
+ }
+ else
+ node.model = 0; /* Like the default constructor. */
+ }
+
+ inline Item(const AtomicValue *const a)
+ {
+ /* Note, the implementation is a copy of the constructor above. */
+
+ if(a)
+ {
+ atomicValue = a;
+ atomicValue->ref.ref();
+
+ /* Signal that we're housing an atomic value. */
+ node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
+ }
+ else
+ node.model = 0; /* Like the default constructor. */
+ }
+
+ inline ~Item()
+ {
+ if(isAtomicValue() && !atomicValue->ref.deref())
+ delete atomicValue;
+ }
+
+ inline Item &operator=(const Item &other)
+ {
+ Q_ASSERT_X(sizeof(QXmlNodeModelIndex) >= sizeof(AtomicValue *), Q_FUNC_INFO,
+ "If this doesn't hold, we won't copy all data.");
+
+ if(other.isAtomicValue())
+ other.atomicValue->ref.ref();
+
+ if(isAtomicValue())
+ {
+ if(!atomicValue->ref.deref())
+ delete atomicValue;
+ }
+
+ node = other.node;
+
+ return *this;
+ }
+
+ template<typename TCastTarget>
+ inline TCastTarget *as() const
+ {
+#if defined(Patternist_DEBUG) && !defined(Q_CC_XLC)
+/* At least on aix-xlc-64, the compiler cries when it sees dynamic_cast. */
+ Q_ASSERT_X(atomicValue == 0 || dynamic_cast<const TCastTarget *>(atomicValue),
+ Q_FUNC_INFO,
+ "The cast is invalid. This class does not inherit the cast target.");
+#endif
+ return const_cast<TCastTarget *>(static_cast<const TCastTarget *>(atomicValue));
+ }
+
+ /**
+ * @short Returns the string value of this Item.
+ *
+ * In the case of a node, it is the node value corresponding to
+ * the particular node type. For atomic values, it is equivalent
+ * to the value cast as <tt>xs:string</tt>.
+ *
+ * Conceptually, this functions corresponds to the <tt>dm:string-value</tt> accessor.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/#dm-string-value">XQuery 1.0 and
+ * XPath 2.0 Data Model, 5.13 string-value Accessor</a>
+ * @returns the string value.
+ */
+ inline QString stringValue() const
+ {
+ if(isAtomicValue())
+ return atomicValue->stringValue();
+ else
+ return asNode().stringValue();
+ }
+
+ /**
+ * @short Returns the typed value of this item.
+ *
+ * Conceptually, this functions corresponds to the <tt>dm:typed-value</tt> accessor. Here are
+ * examples of what the typed value of an Item is:
+ *
+ * - The typed value of an atomic value is always the atomic value itself.
+ * - A comment node has always a typed value of type @c xs:string
+ * - For attribute and element nodes, the typed value can be arbitrary. For example, an
+ * element can have a sequence of @c xs:dateTime instances.
+ *
+ * @returns the typed value of this item
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/#dm-typed-value">XQuery 1.0 and
+ * XPath 2.0 Data Model, 5.15 typed-value Accessor</a>
+ */
+ Item::Iterator::Ptr sequencedTypedValue() const;
+
+ /**
+ * @short Determines whether this item is an atomic value, or a node.
+ *
+ * If this Item is @c null, @c false is returned.
+ *
+ * @see isNode()
+ * @returns @c true if it is an atomic value, otherwise @c false.
+ */
+ inline bool isAtomicValue() const
+ {
+ /* Setting node.model to ~0, signals that it's an atomic value. */
+ return node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
+ }
+
+ /**
+ * @short Determines whether this item is an atomic value, or a node.
+ *
+ * If this Item is @c null, false is returned.
+ *
+ * @see isAtomicValue()
+ * @returns @c true if this item is a node, otherwise @c false.
+ */
+ inline bool isNode() const
+ {
+ //return !isAtomicValue();
+ return node.model && node.model != reinterpret_cast<QAbstractXmlNodeModel *>(~0);
+ }
+
+ /**
+ * @short Returns the ItemType this Item is of.
+ *
+ * For example, if this Item is an XML node, more specifically a text node,
+ * <tt>text()</tt> is returned. That is, BuiltinTypes::text. However, if this
+ * Item is an atomic value of type <tt>xs:long</tt> that is what's returned,
+ * BuiltinTypes::xsLong.
+ *
+ * @returns the type of this Item.
+ */
+ inline QExplicitlySharedDataPointer<ItemType> type() const
+ {
+ if(isAtomicValue())
+ return atomicValue->type();
+ else
+ return asNode().type();
+ }
+
+ inline const AtomicValue *asAtomicValue() const
+ {
+ Q_ASSERT(isAtomicValue());
+ return atomicValue;
+ }
+
+ inline const QXmlNodeModelIndex &asNode() const
+ {
+ Q_ASSERT_X(isNode() || isNull(), Q_FUNC_INFO,
+ "This item isn't a valid QXmlNodeModelIndex.");
+ Q_ASSERT_X(sizeof(QXmlNodeModelIndex) == sizeof(QPatternist::NodeIndexStorage), Q_FUNC_INFO,
+ "If this doesn't hold, something is wrong.");
+
+ return reinterpret_cast<const QXmlNodeModelIndex &>(node);
+ }
+
+ inline operator bool() const
+ {
+ return node.model;
+ }
+
+ inline bool isNull() const
+ {
+ return !node.model;
+ }
+
+ inline void reset()
+ {
+ /* Note that this function should be equal to the default
+ * constructor. */
+ node.model = 0;
+ node.data = 0;
+ }
+
+ static inline Item fromPublic(const QXmlItem &i)
+ {
+ const Item it(i.m_node);
+ if(it.isAtomicValue())
+ it.asAtomicValue()->ref.ref();
+
+ return it;
+ }
+
+ static inline QXmlItem toPublic(const Item &i)
+ {
+ return QXmlItem(i);
+ }
+
+ private:
+ union
+ {
+ NodeIndexStorage node;
+ const AtomicValue *atomicValue;
+ };
+ };
+
+ template<typename T>
+ inline Item toItem(const QExplicitlySharedDataPointer<T> atomicValue)
+ {
+ return Item(atomicValue.data());
+ }
+
+ /**
+ * This is an overload, provided for convenience.
+ * @relates QXmlNodeModelIndex
+ */
+ static inline QString formatData(const QXmlNodeModelIndex node)
+ {
+ return node.stringValue(); // This can be improved a lot.
+ }
+}
+
+ inline QXmlName QXmlNodeModelIndex::name() const
+ {
+ return m_storage.model->name(*this);
+ }
+
+ inline QXmlNodeModelIndex QXmlNodeModelIndex::root() const
+ {
+ return m_storage.model->root(*this);
+ }
+
+ inline QXmlNodeModelIndex::Iterator::Ptr QXmlNodeModelIndex::iterate(const QXmlNodeModelIndex::Axis axis) const
+ {
+ return m_storage.model->iterate(*this, axis);
+ }
+
+ inline QUrl QXmlNodeModelIndex::documentUri() const
+ {
+ return m_storage.model->documentUri(*this);
+ }
+
+ inline QUrl QXmlNodeModelIndex::baseUri() const
+ {
+ return m_storage.model->baseUri(*this);
+ }
+
+ inline QXmlNodeModelIndex::NodeKind QXmlNodeModelIndex::kind() const
+ {
+ return m_storage.model->kind(*this);
+ }
+
+ inline bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const
+ {
+ return m_storage.model->isDeepEqual(*this, other);
+ }
+
+ inline QXmlNodeModelIndex::DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const
+ {
+ Q_ASSERT_X(model() == other.model(), Q_FUNC_INFO, "The API docs guarantees the two nodes are from the same model");
+ return m_storage.model->compareOrder(*this, other);
+ }
+
+ inline bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const
+ {
+ return m_storage.model == other.m_storage.model &&
+ m_storage.data == other.m_storage.data &&
+ m_storage.additionalData == other.m_storage.additionalData;
+ }
+
+ inline void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const
+ {
+ m_storage.model->sendNamespaces(*this, receiver);
+ }
+
+ inline QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const
+ {
+ return m_storage.model->namespaceBindings(*this);
+ }
+
+ inline QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const
+ {
+ return m_storage.model->namespaceForPrefix(*this, prefix);
+ }
+
+ inline QString QXmlNodeModelIndex::stringValue() const
+ {
+ return m_storage.model->stringValue(*this);
+ }
+
+ inline QPatternist::ItemType::Ptr QXmlNodeModelIndex::type() const
+ {
+ return m_storage.model->type(*this);
+ }
+
+ inline QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const
+ {
+ return m_storage.model->sequencedTypedValue(*this);
+ }
+
+ inline QXmlItem::QXmlItem(const QPatternist::Item &i) : m_node(i.node)
+ {
+ if(isAtomicValue())
+ m_atomicValue->ref.ref();
+ }
+
+Q_DECLARE_TYPEINFO(QPatternist::Item::Iterator::Ptr, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QPatternist::AtomicValue, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qnodebuilder.cpp b/src/xmlpatterns/data/qnodebuilder.cpp
new file mode 100644
index 0000000..2463a4d
--- /dev/null
+++ b/src/xmlpatterns/data/qnodebuilder.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnodebuilder_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qnodebuilder_p.h b/src/xmlpatterns/data/qnodebuilder_p.h
new file mode 100644
index 0000000..e311d63
--- /dev/null
+++ b/src/xmlpatterns/data/qnodebuilder_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NodeBuilder_H
+#define Patternist_NodeBuilder_H
+
+#include "qitem_p.h"
+#include "qabstractxmlreceiver.h"
+#include "qautoptr_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Receives QAbstractXmlReceiver events and builds a node tree
+ * in memory that afterwards can be retrieved via builtNode()
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NodeBuilder : public QAbstractXmlReceiver
+ {
+ public:
+ typedef AutoPtr<NodeBuilder> Ptr;
+
+ inline NodeBuilder()
+ {
+ }
+
+ /**
+ * @short Returns the document that has been built.
+ *
+ * If this function is called before any events have been received, the result is undefined.
+ *
+ * The top node that was constructed can be retrieved by calling
+ * NodeModel::root() on the returned NodeModel.
+ *
+ * This function is not @c const, because some implementations delay
+ * the node construction until the node is needed. Also, text nodes are
+ * difficult, at best, to construct until one knows that all text content
+ * has been received(which a call to this function in a natural way
+ * signals).
+ */
+ virtual QAbstractXmlNodeModel::Ptr builtDocument() = 0;
+
+ /**
+ * @short Creates a copy of this NodeBuilder, that operates independently of
+ * this NodeBuilder.
+ *
+ * The caller owns the returned instance.
+ */
+ virtual NodeBuilder::Ptr create(const QUrl &baseURI) const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qnodemodel.cpp b/src/xmlpatterns/data/qnodemodel.cpp
new file mode 100644
index 0000000..5d713c3
--- /dev/null
+++ b/src/xmlpatterns/data/qnodemodel.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qnamespaceresolver_p.h"
+
+#include "qitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qqnamevalue.cpp b/src/xmlpatterns/data/qqnamevalue.cpp
new file mode 100644
index 0000000..72ab6eb
--- /dev/null
+++ b/src/xmlpatterns/data/qqnamevalue.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qbuiltintypes_p.h"
+#include "qxpathhelper_p.h"
+
+#include "qqnamevalue_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QNameValue::QNameValue(const NamePool::Ptr &np, const QXmlName name) : m_qName(name)
+ , m_namePool(np)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(m_namePool);
+}
+
+QNameValue::Ptr QNameValue::fromValue(const NamePool::Ptr &np, const QXmlName name)
+{
+ Q_ASSERT(!name.isNull());
+ return QNameValue::Ptr(new QNameValue(np, name));
+}
+
+QString QNameValue::stringValue() const
+{
+ return m_namePool->toLexical(m_qName);
+}
+
+ItemType::Ptr QNameValue::type() const
+{
+ return BuiltinTypes::xsQName;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qqnamevalue_p.h b/src/xmlpatterns/data/qqnamevalue_p.h
new file mode 100644
index 0000000..93edbc7
--- /dev/null
+++ b/src/xmlpatterns/data/qqnamevalue_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_QNameValue_H
+#define Patternist_QNameValue_H
+
+#include "qitem_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:QName type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @see QNameConstructor::expandQName()
+ * @see XPathHelper::isQName()
+ * @see QXmlUtils
+ */
+ class QNameValue : public AtomicValue
+ {
+ public:
+ friend class CommonValues;
+ friend class QNameComparator;
+
+ typedef QExplicitlySharedDataPointer<QNameValue> Ptr;
+
+ /**
+ * Constructs a QNameValue that represents @p name.
+ *
+ * @param name the QName. May not be @c null.
+ * @param np the NamePool.
+ * @see QNameConstructor::expandQName()
+ * @see XPathHelper::isQName()
+ * @see QXmlUtils
+ */
+ static QNameValue::Ptr fromValue(const NamePool::Ptr &np, const QXmlName name);
+
+ virtual QString stringValue() const;
+
+ virtual ItemType::Ptr type() const;
+
+ inline QXmlName qName() const
+ {
+ return m_qName;
+ }
+
+ private:
+ QNameValue(const NamePool::Ptr &np, const QXmlName name);
+
+ const QXmlName m_qName;
+ const NamePool::Ptr m_namePool;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qresourceloader.cpp b/src/xmlpatterns/data/qresourceloader.cpp
new file mode 100644
index 0000000..c727253
--- /dev/null
+++ b/src/xmlpatterns/data/qresourceloader.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+
+#include "qresourceloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ResourceLoader::~ResourceLoader()
+{
+}
+
+bool ResourceLoader::isUnparsedTextAvailable(const QUrl &uri,
+ const QString &encoding)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ Q_UNUSED(encoding);
+ return false;
+}
+
+ItemType::Ptr ResourceLoader::announceUnparsedText(const QUrl &uri)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ return ItemType::Ptr();
+}
+
+Item ResourceLoader::openUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ Q_UNUSED(encoding);
+ Q_UNUSED(context);
+ Q_UNUSED(where);
+ return Item();
+}
+
+Item ResourceLoader::openDocument(const QUrl &uri,
+ const ReportContext::Ptr &context)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ Q_UNUSED(context); /* Needed when compiling in release mode. */
+ return Item();
+}
+
+SequenceType::Ptr ResourceLoader::announceDocument(const QUrl &uri, const Usage)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ return SequenceType::Ptr();
+}
+
+bool ResourceLoader::isDocumentAvailable(const QUrl &uri)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ return false;
+}
+
+Item::Iterator::Ptr ResourceLoader::openCollection(const QUrl &uri)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ return Item::Iterator::Ptr();
+}
+
+SequenceType::Ptr ResourceLoader::announceCollection(const QUrl &uri)
+{
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+ Q_UNUSED(uri); /* Needed when compiling in release mode. */
+ return SequenceType::Ptr();
+}
+
+void ResourceLoader::clear(const QUrl &uri)
+{
+ Q_UNUSED(uri);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qresourceloader_p.h b/src/xmlpatterns/data/qresourceloader_p.h
new file mode 100644
index 0000000..4ed4342
--- /dev/null
+++ b/src/xmlpatterns/data/qresourceloader_p.h
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ResourceLoader_H
+#define Patternist_ResourceLoader_H
+
+#include "qitem_p.h"
+#include "qreportcontext_p.h"
+#include "qsequencetype_p.h"
+#include "qsourcelocationreflection_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QUrl;
+
+namespace QPatternist
+{
+ /**
+ * @short Responsible for handling requests for opening files and node collections.
+ *
+ * ResourceLoader is a callback used for opening files, requested
+ * via the functions <tt>fn:document()</tt> and <tt>fn:unparsed-text()</tt>;
+ * and node collections, requested via <tt>fn:collection()</tt>. Patternist uses the
+ * ResourceLoader at compile time,
+ * via StaticContext::resourceLoader(), and at runtime, via DynamicContext::resourceLoader().
+ *
+ * The ResourceLoader takes care of loading "external resources" in a way specific to the data
+ * model Patternist is using. For example, perhaps the opening of documents should pass
+ * a security policy, or a collection should map to nodes in a virtual filesystem or a database.
+ *
+ * From Patternist's perspective, the ResourceLoader provides two things:
+ *
+ * - At compile time, it calls announceDocument(), announceCollection() and announceUnparsedText()
+ * if it knows the URIs at compile time in order to retrieve the static types of the data the URIs
+ * maps to. This is used for more efficiently compiling the query and to better report errors
+ * at compile time.
+ * - To open document and node collections at runtime.
+ *
+ * From the user's or the data model's perspective, the ResourceLoader most notably provides
+ * a hint to what resources a query will load at runtime, and therefore provides an opportunity
+ * to prepare in advance for that. For example, between the compile and runtime stage,
+ * the ResourceLoader sub-class can be asked to pre-load documents in an asynchronous
+ * and simultaneous way, such that the runtime stage is faster and doesn't
+ * freeze a graphical interface.
+ *
+ * The announce functions are not guaranteed to be called. The loading functions can be called
+ * with an URI that an announce function hasn't been called with.
+ *
+ * The default implementations of ResourceLoader's virtual functions all signals that no
+ * resources can be loaded. This means ResourceLoader must be sub-classed, in order to
+ * be able to load resources.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT ResourceLoader : public QSharedData
+ {
+ public:
+ enum Usage
+ {
+ /**
+ * Communicates that the URI may be used during query evaluation.
+ * For example, zero times or very many times.
+ *
+ * Typically this hint is given when the URI is available at
+ * compile-time, but it is used inside a conditional statement
+ * whose branching cannot be determined at compile time.
+ */
+ MayUse,
+
+ /**
+ * Communicates that the URI will always be used at query
+ * evaluation.
+ */
+ WillUse
+ };
+
+ typedef QExplicitlySharedDataPointer<ResourceLoader> Ptr;
+ inline ResourceLoader() {}
+ virtual ~ResourceLoader();
+
+ /**
+ * @short Calls to this function are generated by calls to the
+ * <tt>fn:unparsed-text-available()</tt> function.
+ *
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @returns @c true if calling openUnparsedText() while passing @p uri will successfully load
+ * the document.
+ * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL Transformations
+ * (XSLT) Version 2.0, 16.2 Reading Text Files</a>
+ */
+ virtual bool isUnparsedTextAvailable(const QUrl &uri,
+ const QString &encoding);
+
+ /**
+ * @short May be called by the compilation framework at compile time to report that an
+ * unparsed text(plain text) file referenced by @p uri will be loaded at runtime.
+ *
+ * This function can be called an arbitrary amount of times for the same URI. How many times
+ * it is called for a URI has no meaning(beyond the first call, that is). For what queries
+ * the compilation framework can determine what always will be loaded is generally undefined. It
+ * depends on factors such as how simple the query is what information that is statically
+ * available and subsequently what optimizations that can apply.
+ *
+ * Calls to this function are generated by calls to the <tt>fn:unparsed-text()</tt> function.
+ *
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL Transformations
+ * (XSLT) Version 2.0, 16.2 Reading Text Files</a>
+ * @returns
+ * - @c null if no unparsed file can be loaded for @p uri
+ * - The item type that the value loaded by @p uri will be an instance of. This is
+ * typically @c xs:string
+ */
+ virtual ItemType::Ptr announceUnparsedText(const QUrl &uri);
+
+ /**
+ * @short Calls to this function are generated by calls to the <tt>fn:unparsed-text()</tt> function.
+ *
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @param encoding the encoding to use. If empty, the user hasn't
+ * expressed any encoding to use.
+ * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL Transformations
+ * (XSLT) Version 2.0, 16.2 Reading Text Files</a>
+ * @returns
+ * - @c null if no unparsed file can be loaded for @p uri
+ * - An @c xs:string value(or subtype) containing the content of the file identified
+ * by @p uri as text. Remember that its type must match the sequence type
+ * returned by announceUnparsedText()
+ */
+ virtual Item openUnparsedText(const QUrl &uri,
+ const QString &encoding,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const where);
+
+ /**
+ * @short Calls to this function are generated by calls to the <tt>fn:document()</tt>
+ * or <tt>fn:doc()</tt> function.
+ *
+ * @note This function is responsible for execution stability. Subsequent calls
+ * to this function with the same URI should result in QXmlNodeModelIndex instances that have
+ * the same identity. However, in some cases this stability is not of interest, see
+ * the specification for details.
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @see QXmlNodeModelIndex::identity()
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-doc">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.5.4 fn:doc</a>
+ * @see <a href="http://www.w3.org/TR/xslt20/#document">XSL Transformations
+ * (XSLT) Version 2.0, 16.1 Multiple Source Documents</a>
+ * @returns
+ * - @c null if no document can be loaded for @p uri
+ * - A QXmlNodeModelIndex representing the document identified by @p uri. Remember that the QXmlNodeModelIndex
+ * must match the sequence type returned by announceDocument()
+ */
+ virtual Item openDocument(const QUrl &uri,
+ const ReportContext::Ptr &context);
+
+ /**
+ * @short May be called by the compilation framework at compile time to report that an
+ * XML document referenced by @p uri will be loaded at runtime.
+ *
+ * This function can be called an arbitrary amount of times for the same URI, but different
+ * @p usageHint values. How many times it is called for a URI has no meaning(beyond the first call,
+ * that is). For what queries the compilation framework can determine what always will be
+ * loaded is generally undefined. It
+ * depends on factors such as the complexity of the query, what information that is statically
+ * available and subsequently what optimizations that can be applied.
+ *
+ * Calls to this function are generated by calls to the <tt>fn:document()</tt>
+ * or <tt>fn:doc()</tt> function.
+ *
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @param usageHint A hint to how the URI will be used.
+ * @returns
+ * - @c null if the ResourceLoader can determine at this stage that no document
+ * referenced by @p uri will ever be possible to load.
+ * - The appropriate sequence type if loading @p uri succeeds at runtime. This must be
+ * CommonSequenceTypes::zeroOrOneDocument, CommonSequenceTypes::exactlyOneDocument or
+ * a sequence type that is a sub type of it.
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-doc">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.5.4 fn:doc</a>
+ * @see <a href="http://www.w3.org/TR/xslt20/#document">XSL Transformations
+ * (XSLT) Version 2.0, 16.1 Multiple Source Documents</a>
+ */
+ virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint);
+
+ /**
+ * @short Calls to this function are generated by calls to the <tt>fn:doc-available()</tt> function.
+ *
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @returns @c true if calling openDocument() while passing @p uri will successfully load
+ * the document.
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-doc-available">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.5.5 fn:doc-available</a>
+ * @see <a href="http://www.w3.org/TR/xslt20/#document">XSL Transformations
+ * (XSLT) Version 2.0, 16.1 Multiple Source Documents</a>
+ */
+ virtual bool isDocumentAvailable(const QUrl &uri);
+
+ /**
+ * @short Calls to this function are generated by calls to the <tt>fn:collection()</tt> function.
+ *
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-collection">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.5.6 fn:collection</a>
+ * @returns
+ * - @c null if no node collection can be loaded for @p uri
+ * - An QAbstractXmlForwardIterator representing the content identified by @p uri. Remember that the content
+ * of the QAbstractXmlForwardIterator must match the sequence type returned by announceCollection()
+ */
+ virtual Item::Iterator::Ptr openCollection(const QUrl &uri);
+
+ /**
+ * @short May be called by the compilation framework at compile time to report that an
+ * node collection referenced by @p uri will be loaded at runtime.
+ *
+ * This function can be called an arbitrary amount of times for the same URI. How many times
+ * it is called for a URI has no meaning(beyond the first call, that is). For what queries
+ * the compilation framework can determine what always will be loaded is generally undefined. It
+ * depends on factors such as how simple the query is what information that is statically
+ * available and subsequently what optimizations that can apply.
+ *
+ * Calls to this function are generated by calls to the <tt>fn:collection()</tt> function.
+ *
+ * @note This function is responsible for execution stability. Subsequent calls
+ * to this function with the same URI should result in QXmlNodeModelIndex instances that have
+ * the same identity. However, in some cases this stability is not of interest, see
+ * the specification for details.
+ * @param uri A URI identifying the resource to retrieve. The URI is guaranteed
+ * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative()
+ * returns @c false).
+ * @returns
+ * - @c null if the ResourceLoader can determine at this stage that no document
+ * referenced by @p uri will ever be possible to load.
+ * - The appropriate sequence type if loading @p uri succeeds at runtime. This must be
+ * CommonSequenceTypes::zeroOrMoreNodes or a sequence type that is a sub type of it.
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-collection">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.5.6 fn:collection</a>
+ */
+ virtual SequenceType::Ptr announceCollection(const QUrl &uri);
+
+ /**
+ * @short Asks to unload @p uri from its document pool, such that a
+ * subsequent request will require a new read.
+ *
+ * The default implementation does nothing.
+ */
+ virtual void clear(const QUrl &uri);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qschemadatetime.cpp b/src/xmlpatterns/data/qschemadatetime.cpp
new file mode 100644
index 0000000..b91f5f1
--- /dev/null
+++ b/src/xmlpatterns/data/qschemadatetime.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+
+#include "qschemadatetime_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DateTime::DateTime(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+DateTime::Ptr DateTime::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(-?)" /* Any preceding minus. */
+ "(\\d{4,})" /* The year part. */
+ "-" /* Delimiter. */
+ "(\\d{2})" /* The month part. */
+ "-" /* Delimiter. */
+ "(\\d{2})" /* The day part. */
+ "T" /* Delimiter. */
+ "(\\d{2})" /* Hour part */
+ ":" /* Delimiter. */
+ "(\\d{2})" /* Minutes part */
+ ":" /* Delimiter. */
+ "(\\d{2,})" /* Seconds part. */
+ "(?:\\.(\\d+))?" /* Milli seconds part. */
+ "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */
+ "\\s*$" /* Any whitespace at the end. */))),
+ /*zoneOffsetSignP*/ 9,
+ /*zoneOffsetHourP*/ 10,
+ /*zoneOffsetMinuteP*/ 11,
+ /*zoneOffsetUTCSymbolP*/ 12,
+ /*yearP*/ 2,
+ /*monthP*/ 3,
+ /*dayP*/ 4,
+ /*hourP*/ 5,
+ /*minutesP*/ 6,
+ /*secondsP*/ 7,
+ /*msecondsP*/ 8,
+ /*yearSignP*/ 1);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : DateTime::Ptr(new DateTime(retval));
+}
+
+DateTime::Ptr DateTime::fromDateTime(const QDateTime &dt)
+{
+ Q_ASSERT(dt.isValid());
+ return DateTime::Ptr(new DateTime(dt));
+}
+
+Item DateTime::fromValue(const QDateTime &dt) const
+{
+ Q_ASSERT(dt.isValid());
+ return fromDateTime(dt);
+}
+
+QString DateTime::stringValue() const
+{
+ return dateToString() + QLatin1Char('T') + timeToString() + zoneOffsetToString();
+}
+
+ItemType::Ptr DateTime::type() const
+{
+ return BuiltinTypes::xsDateTime;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qschemadatetime_p.h b/src/xmlpatterns/data/qschemadatetime_p.h
new file mode 100644
index 0000000..a92b27b
--- /dev/null
+++ b/src/xmlpatterns/data/qschemadatetime_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DateTime_H
+#define Patternist_DateTime_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @file
+ * @short Contains class DateTime. This file was originally called qdatetime_p.h,
+ * but various build systems cannot handle that that name happens to be
+ * identical to another one, the one in QtCore.
+ */
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:dateTime type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class DateTime : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static DateTime::Ptr fromLexical(const QString &string);
+ static DateTime::Ptr fromDateTime(const QDateTime &dt);
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+ virtual Item fromValue(const QDateTime &dt) const;
+
+ protected:
+ friend class CommonValues;
+
+ DateTime(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qschemanumeric.cpp b/src/xmlpatterns/data/qschemanumeric.cpp
new file mode 100644
index 0000000..f5cc323
--- /dev/null
+++ b/src/xmlpatterns/data/qschemanumeric.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <math.h>
+
+#include "qabstractfloat_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qdecimal_p.h"
+#include "qinteger_p.h"
+
+#include "qschemanumeric_p.h"
+
+/**
+ * @file Contains class Numeric. This file was originally called qnumeric.cpp,
+ * but was renamed to stay consistent with qschemanumeric_p.h
+ */
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicValue::Ptr Numeric::fromLexical(const QString &number)
+{
+ Q_ASSERT(!number.isEmpty());
+ Q_ASSERT_X(!number.contains(QLatin1Char('e')) &&
+ !number.contains(QLatin1Char('E')),
+ Q_FUNC_INFO, "Should not contain any e/E");
+
+ if(number.contains(QLatin1Char('.'))) /* an xs:decimal. */
+ return Decimal::fromLexical(number);
+ else /* It's an integer, of some sort. E.g, -3, -2, -1, 0, 1, 2, 3 */
+ return Integer::fromLexical(number);
+}
+
+xsDouble Numeric::roundFloat(const xsDouble val)
+{
+ if(qIsInf(val) || AbstractFloat<true>::isEqual(val, 0.0))
+ return val;
+ else if(qIsNaN(val))
+ return val;
+ else
+ {
+ if(val >= -0.5 && val < 0)
+ return -0.0;
+ else
+ return ::floor(val + 0.5);
+
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qschemanumeric_p.h b/src/xmlpatterns/data/qschemanumeric_p.h
new file mode 100644
index 0000000..792eb58
--- /dev/null
+++ b/src/xmlpatterns/data/qschemanumeric_p.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Numeric_H
+#define Patternist_Numeric_H
+
+#include "qitem_p.h"
+#include "qprimitives_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @file
+ * @short Contains class Numeric. This file was originally called qnumeric_p.h,
+ * but various build systems cannot handle that that name happens to be
+ * identical to another one, the one in QtCore.
+ */
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all numeric values.
+ *
+ * @section creation Creating Instances
+ *
+ * @todo
+ * - Depending on what type of val
+ * - Numeric::createFromString
+ * - Various classes has ::Zero(), ::PosINF(), ::NaN(), NegINF()
+ * - Never use constructor, use createFromNative, or createFromString.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-operators/#numeric-functions">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6 Functions and Operators on Numerics</a>
+ * @see <a href="http://www.w3.org/TR/xquery-operators/#func-overloading">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 1.2 Function Overloading</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ * @todo discuss data hierarchy the non existatnt number data type
+ */
+ class Numeric : public AtomicValue
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<Numeric> Ptr;
+
+ /**
+ * Creates a Numeric sub-class that is appropriate for @p number.
+ *
+ * @note usages of e/E is not handled; Double::fromLexical should
+ * be used in that case. There is no function similar to fromLexical that also
+ * takes double values into account(because that distinction is done in the scanner).
+ *
+ * Currently used in the parser to create appropriate expressions.
+ */
+ static AtomicValue::Ptr fromLexical(const QString &number);
+
+ /**
+ * @returns the particular number's value as a native representation of
+ * the type xs:double. This can be considered that the value is cast to
+ * xs:double.
+ */
+ virtual xsDouble toDouble() const = 0;
+
+ /**
+ * @returns the particular number's value as a native representation of
+ * the type xs:integer. This can be considered that the value is cast to
+ * xs:integer.
+ */
+ virtual xsInteger toInteger() const = 0;
+
+ /**
+ * @returns the number as an unsigned integer. If the value is not
+ * unsigned, the code asserts and behavior is undefined.
+ */
+ virtual qulonglong toUnsignedInteger() const = 0;
+
+ /**
+ * @returns the particular number's value as a native representation of
+ * the type xs:float. This can be considered that the value is cast to
+ * xs:float.
+ */
+ virtual xsFloat toFloat() const = 0;
+
+ /**
+ * @returns the particular number's value as a native representation of
+ * the type xs:decimal. This can be considered that the value is cast to
+ * xs:decimal.
+ */
+ virtual xsFloat toDecimal() const = 0;
+
+ /**
+ * Performs the algorithm specified for the function fn:round on this Numeric,
+ * and whose result is returned.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-round">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.4.4 fn:round</a>
+ */
+ virtual Numeric::Ptr round() const = 0;
+
+ /**
+ * Performs rounding as defined for the fn:round-half-to-even on this Numeric,
+ * and whose result is returned.
+ *
+ * @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>
+ */
+ virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const = 0;
+
+ /**
+ * Performs the algorithm specified for the function fn:floor on this Numeric,
+ * and whose result is returned.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-floor">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.4.3 fn:floor</a>
+ */
+ virtual Numeric::Ptr floor() const = 0;
+
+ /**
+ * Performs the algorithm specified for the function fn:ceiling on this Numeric,
+ * and whose result is returned.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-ceiling">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.4.2 fn:ceiling</a>
+ */
+ virtual Numeric::Ptr ceiling() const = 0;
+
+ /**
+ * Performs the algorithm specified for the function fn:abs on this Numeric,
+ * and whose result is returned.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-ceiling">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.4.1 fn:abs</a>
+ */
+ virtual Numeric::Ptr abs() const = 0;
+
+ /**
+ * Determines whether this Numeric is not-a-number, @c NaN. For numeric types
+ * that cannot represent @c NaN, this function should return @c false.
+ *
+ * @returns @c true if this Numeric is @c NaN
+ */
+ virtual bool isNaN() const = 0;
+
+ /**
+ * Determines whether this Numeric is an infinite number. Signedness
+ * is irrelevant, -INF as well as INF is considered infinity.
+ *
+ * For numeric types that cannot represent infinity, such as xs:integer
+ * , this function should return @c false.
+ *
+ * @returns @c true if this Numeric is an infinite number
+ */
+ virtual bool isInf() const = 0;
+
+ /**
+ * Unary minus.
+ */
+ virtual Item toNegated() const = 0;
+
+ /**
+ * @short Returns @c true if this value is signed. If @c false is
+ * returned, the value is unsigned.
+ *
+ * For float and decimal values, @c xs:double, @c xs:float and @c
+ * xs:decimal, the code asserts and behavior is undefined.
+ */
+ virtual bool isSigned() const = 0;
+
+ protected:
+ /**
+ * @short Implements @c fn:round() for types implemented with floating
+ * point.
+ *
+ * MS Windows and at least IRIX does not have C99's nearbyint() function(see the man
+ * page), so we reinvent it.
+ */
+ static xsDouble roundFloat(const xsDouble val);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qschematime.cpp b/src/xmlpatterns/data/qschematime.cpp
new file mode 100644
index 0000000..dc382d8
--- /dev/null
+++ b/src/xmlpatterns/data/qschematime.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+
+#include "qschematime_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SchemaTime::SchemaTime(const QDateTime &dateTime) : AbstractDateTime(dateTime)
+{
+}
+
+SchemaTime::Ptr SchemaTime::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable( // STATIC DATA
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(\\d{2})" /* Hour part */
+ ":" /* Delimiter. */
+ "(\\d{2})" /* Minutes part */
+ ":" /* Delimiter. */
+ "(\\d{2,})" /* Seconds part. */
+ "(?:\\.(\\d+))?" /* Milli seconds part. */
+ "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */
+ "\\s*$" /* Any terminating whitespace. */))),
+ /*zoneOffsetSignP*/ 5,
+ /*zoneOffsetHourP*/ 6,
+ /*zoneOffsetMinuteP*/ 7,
+ /*zoneOffsetUTCSymbolP*/ 8,
+ /*yearP*/ -1,
+ /*monthP*/ -1,
+ /*dayP*/ -1,
+ /*hourP*/ 1,
+ /*minutesP*/ 2,
+ /*secondsP*/ 3,
+ /*msecondsP*/ 4);
+
+ AtomicValue::Ptr err;
+ const QDateTime retval(create(err, lexical, captureTable));
+
+ return err ? err : SchemaTime::Ptr(new SchemaTime(retval));
+}
+
+SchemaTime::Ptr SchemaTime::fromDateTime(const QDateTime &dt)
+{
+ Q_ASSERT(dt.isValid());
+ /* Singleton value, allocated once instead of each time it's needed. */
+ // STATIC DATA
+ static const QDate time_defaultDate(AbstractDateTime::DefaultYear,
+ AbstractDateTime::DefaultMonth,
+ AbstractDateTime::DefaultDay);
+
+ QDateTime result;
+ copyTimeSpec(dt, result);
+
+ result.setDate(time_defaultDate);
+ result.setTime(dt.time());
+
+ return SchemaTime::Ptr(new SchemaTime(result));
+}
+
+Item SchemaTime::fromValue(const QDateTime &dt) const
+{
+ Q_ASSERT(dt.isValid());
+ return fromDateTime(dt);
+}
+
+QString SchemaTime::stringValue() const
+{
+ return timeToString() + zoneOffsetToString();
+}
+
+ItemType::Ptr SchemaTime::type() const
+{
+ return BuiltinTypes::xsTime;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qschematime_p.h b/src/xmlpatterns/data/qschematime_p.h
new file mode 100644
index 0000000..1d89bc5
--- /dev/null
+++ b/src/xmlpatterns/data/qschematime_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Time_H
+#define Patternist_Time_H
+
+#include "qabstractdatetime_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:time type.
+ *
+ * The header file for this class was originally called Time.h, but this
+ * clashed with a system header on MinGW.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class SchemaTime : public AbstractDateTime
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static SchemaTime::Ptr fromLexical(const QString &string);
+ static SchemaTime::Ptr fromDateTime(const QDateTime &dt);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+ virtual Item fromValue(const QDateTime &dt) const;
+
+ protected:
+ friend class CommonValues;
+
+ SchemaTime(const QDateTime &dateTime);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qsequencereceiver.cpp b/src/xmlpatterns/data/qsequencereceiver.cpp
new file mode 100644
index 0000000..212c514
--- /dev/null
+++ b/src/xmlpatterns/data/qsequencereceiver.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+
+#include "qabstractxmlreceiver.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QAbstractXmlReceiver::~QAbstractXmlReceiver()
+{
+}
+
+template<const QXmlNodeModelIndex::Axis axis>
+void QAbstractXmlReceiver::sendFromAxis(const QXmlNodeModelIndex &node)
+{
+ Q_ASSERT(!node.isNull());
+ const QXmlNodeModelIndex::Iterator::Ptr it(node.iterate(axis));
+ QXmlNodeModelIndex next(it->next());
+
+ while(!next.isNull())
+ {
+ sendAsNode(next);
+ next = it->next();
+ }
+}
+
+void QAbstractXmlReceiver::sendAsNode(const Item &outputItem)
+{
+ Q_ASSERT(outputItem);
+ Q_ASSERT(outputItem.isNode());
+ const QXmlNodeModelIndex asNode = outputItem.asNode();
+
+ switch(asNode.kind())
+ {
+ case QXmlNodeModelIndex::Attribute:
+ {
+ attribute(asNode.name(), outputItem.stringValue());
+ break;
+ }
+ case QXmlNodeModelIndex::Element:
+ {
+ startElement(asNode.name());
+
+ /* First the namespaces, then attributes, then the children. */
+ asNode.sendNamespaces(Ptr(const_cast<QAbstractXmlReceiver *>(this)));
+ sendFromAxis<QXmlNodeModelIndex::AxisAttribute>(asNode);
+ sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
+
+ endElement();
+
+ break;
+ }
+ case QXmlNodeModelIndex::Text:
+ {
+ characters(outputItem.stringValue());
+ break;
+ }
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ {
+ processingInstruction(asNode.name(), outputItem.stringValue());
+ break;
+ }
+ case QXmlNodeModelIndex::Comment:
+ {
+ comment(outputItem.stringValue());
+ break;
+ }
+ case QXmlNodeModelIndex::Document:
+ {
+ sendFromAxis<QXmlNodeModelIndex::AxisChild>(asNode);
+ break;
+ }
+ case QXmlNodeModelIndex::Namespace:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
+ }
+}
+
+void QAbstractXmlReceiver::whitespaceOnly(const QStringRef &value)
+{
+ Q_ASSERT_X(value.toString().trimmed().isEmpty(), Q_FUNC_INFO,
+ "The caller must guarantee only whitespace is passed. Use characters() in other cases.");
+ characters(value.toString());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qsequencereceiver_p.h b/src/xmlpatterns/data/qsequencereceiver_p.h
new file mode 100644
index 0000000..b5490fd
--- /dev/null
+++ b/src/xmlpatterns/data/qsequencereceiver_p.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SequenceReceiver_H
+#define Patternist_SequenceReceiver_H
+
+#include <QSharedData>
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A push interface for the XPath Data Model. Similar to SAX's
+ * ContentHandler.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class QAbstractXmlReceiver : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<QAbstractXmlReceiver> Ptr;
+
+ inline QAbstractXmlReceiver()
+ {
+ }
+
+ virtual ~QAbstractXmlReceiver();
+
+ /**
+ * @short Signals the start of an element by name @p name.
+ */
+ virtual void startElement(const QXmlName name) = 0;
+
+ /**
+ * @short Signals the presence of the namespace declaration @p nb.
+ *
+ * This event is received @c after startElement(), as opposed to
+ * SAX, and before any attribute() events.
+ */
+ virtual void namespaceBinding(const QXmlName &nb) = 0;
+
+ /**
+ * @short Signals the end of the current element.
+ */
+ virtual void endElement() = 0;
+
+ /**
+ * @short Signals the presence of an attribute node.
+ *
+ * This function is guaranteed by the caller to always be
+ * called after a call to startElement() or attribute().
+ *
+ * @param name the name of the attribute. Guaranteed to always be
+ * non-null.
+ * @param value the value of the attribute. Guaranteed to always be
+ * non-null.
+ */
+ virtual void attribute(const QXmlName name,
+ const QString &value) = 0;
+
+ virtual void processingInstruction(const QXmlName name,
+ const QString &value) = 0;
+ virtual void comment(const QString &value) = 0;
+
+ /**
+ * @short Sends an Item to this QAbstractXmlReceiver that may be a QXmlNodeModelIndex or an
+ * AtomicValue.
+ */
+ virtual void item(const Item &item) = 0;
+
+ /**
+ * Sends a text node with value @p value. Adjascent text nodes
+ * may be sent. There's no restrictions on @p value, beyond that it
+ * must be valid XML characters. For instance, @p value may contain
+ * only whitespace.
+ *
+ * @see whitespaceOnly()
+ */
+ virtual void characters(const QString &value) = 0;
+
+ /**
+ * This function may be called instead of characters() if, and only if,
+ * @p value consists only of whitespace.
+ *
+ * The caller gurantees that @p value, is not empty.
+ *
+ * By whitespace is meant a sequence of characters that are either
+ * spaces, tabs, or the two new line characters, in any order. In
+ * other words, the whole of Unicode's whitespace category is not
+ * considered whitespace.
+ *
+ * However, there's no guarantee or requirement that whitespaceOnly()
+ * is called for text nodes containing whitespace only, characters()
+ * may be called just as well. This is why the default implementation
+ * for whitespaceOnly() calls characters().
+ *
+ * @see characters()
+ */
+ virtual void whitespaceOnly(const QStringRef &value);
+
+ /**
+ * Start of a document node.
+ */
+ virtual void startDocument() = 0;
+
+ /**
+ * End of a document node.
+ */
+ virtual void endDocument() = 0;
+
+ protected:
+ /**
+ * Treats @p outputItem as an node and calls the appropriate function,
+ * such as attribute() or comment(), depending on its QXmlNodeModelIndex::NodeKind.
+ *
+ * This a helper function sub-classes can use to multi-plex Nodes received
+ * via item().
+ *
+ * @param outputItem must be a QXmlNodeModelIndex.
+ */
+ void sendAsNode(const Item &outputItem);
+
+ private:
+ /**
+ * Call sendAsNode() for each child of @p node. As consistent with the
+ * XPath Data Model, this does not include attribute nodes.
+ */
+ template<const QXmlNodeModelIndex::Axis axis>
+ inline void sendFromAxis(const QXmlNodeModelIndex &node);
+ Q_DISABLE_COPY(QAbstractXmlReceiver)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qsorttuple.cpp b/src/xmlpatterns/data/qsorttuple.cpp
new file mode 100644
index 0000000..598e67b
--- /dev/null
+++ b/src/xmlpatterns/data/qsorttuple.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+
+#include "qbuiltintypes_p.h"
+#include "qsorttuple_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool SortTuple::isAtomicValue() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function.");
+ return false;
+}
+
+QString SortTuple::stringValue() const
+{
+ return QLatin1String("SortTuple");
+}
+
+bool SortTuple::isNode() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function.");
+ return false;
+}
+
+bool SortTuple::hasError() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function.");
+ return false;
+}
+
+Item::Iterator::Ptr SortTuple::typedValue() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "It makes no sense to call this function.");
+ return Item::Iterator::Ptr();
+}
+
+ItemType::Ptr SortTuple::type() const
+{
+ return BuiltinTypes::xsAnyAtomicType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qsorttuple_p.h b/src/xmlpatterns/data/qsorttuple_p.h
new file mode 100644
index 0000000..b407274
--- /dev/null
+++ b/src/xmlpatterns/data/qsorttuple_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SortTuple_H
+#define Patternist_SortTuple_H
+
+#include "qitem_p.h"
+#include "qitem_p.h"
+#include "qitemtype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a value and its sort keys
+ * in FLOWR's <tt>order by</tt> clause.
+ *
+ * SortTuple doesn't correspond to anything in the XPath Data Model and
+ * can therefore well be described as an exotic implementation detail.
+ * Most of its functions asserts because it makes no sense to
+ * call them.
+ *
+ * SortTuple exclusively exists for use with the expressions OrderBy and
+ * ReturnOrderBy, and acts as a carrier between those two for sort keys and
+ * source values.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SortTuple : public AtomicValue
+ {
+ public:
+ /**
+ * @p aSortKeys may be empty.
+ */
+ inline SortTuple(const Item::Iterator::Ptr &aValue,
+ const Item::Vector &aSortKeys) : m_sortKeys(aSortKeys),
+ m_value(aValue)
+ {
+ Q_ASSERT(m_value);
+ Q_ASSERT(!m_sortKeys.isEmpty());
+ }
+
+ /**
+ * A smart pointer wrapping SortTuple instances.
+ */
+ typedef QExplicitlySharedDataPointer<SortTuple> Ptr;
+
+ /**
+ * This function is sometimes called by Literal::description().
+ * This function simply returns "SortTuple".
+ */
+ virtual QString stringValue() const;
+
+ /**
+ * @short Always asserts.
+ */
+ virtual Item::Iterator::Ptr typedValue() const;
+
+ /**
+ * @short Always asserts.
+ */
+ virtual bool isAtomicValue() const;
+
+ /**
+ * @short Always asserts.
+ */
+ virtual bool isNode() const;
+
+ /**
+ * @short Always asserts.
+ */
+ virtual bool hasError() const;
+
+ virtual ItemType::Ptr type() const;
+
+ inline const Item::Vector &sortKeys() const
+ {
+ return m_sortKeys;
+ }
+
+ inline const Item::Iterator::Ptr &value() const
+ {
+ return m_value;
+ }
+
+ private:
+ const Item::Vector m_sortKeys;
+ const Item::Iterator::Ptr m_value;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/quntypedatomic.cpp b/src/xmlpatterns/data/quntypedatomic.cpp
new file mode 100644
index 0000000..ccb65d7
--- /dev/null
+++ b/src/xmlpatterns/data/quntypedatomic.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "quntypedatomic_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UntypedAtomic::UntypedAtomic(const QString &s) : AtomicString(s)
+{
+}
+
+UntypedAtomic::Ptr UntypedAtomic::fromValue(const QString &value)
+{
+ return UntypedAtomic::Ptr(new UntypedAtomic(value));
+}
+
+ItemType::Ptr UntypedAtomic::type() const
+{
+ return BuiltinTypes::xsUntypedAtomic;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/quntypedatomic_p.h b/src/xmlpatterns/data/quntypedatomic_p.h
new file mode 100644
index 0000000..45665ac
--- /dev/null
+++ b/src/xmlpatterns/data/quntypedatomic_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UntypedAtomic_H
+#define Patternist_UntypedAtomic_H
+
+#include "qatomicstring_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the value instance of the @c xs:untypedAtomic type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class UntypedAtomic : public AtomicString
+ {
+ public:
+ friend class CommonValues;
+
+ /**
+ * Creates an instance representing @p value.
+ *
+ * This fromValue function takes no context argument because it doesn't need it -- it
+ * casting to xs:untypedAtomic always succeeds.
+ *
+ * @note This function does not remove the string literal escaping allowed in XPath 2.0
+ */
+ static UntypedAtomic::Ptr fromValue(const QString &value);
+
+ virtual ItemType::Ptr type() const;
+
+ protected:
+
+ UntypedAtomic(const QString &value);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qvalidationerror.cpp b/src/xmlpatterns/data/qvalidationerror.cpp
new file mode 100644
index 0000000..c07b036
--- /dev/null
+++ b/src/xmlpatterns/data/qvalidationerror.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qvalidationerror_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ValidationError::ValidationError(const QString &msg,
+ const ReportContext::ErrorCode code) : m_message(msg),
+ m_code(code)
+{
+}
+
+AtomicValue::Ptr ValidationError::createError(const QString &description,
+ const ReportContext::ErrorCode code)
+{
+ return ValidationError::Ptr(new ValidationError(description, code));
+}
+
+bool ValidationError::hasError() const
+{
+ return true;
+}
+
+QString ValidationError::stringValue() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "stringValue() asked for ValidationError -- it makes no sense.");
+ return QString();
+}
+
+QString ValidationError::message() const
+{
+ return m_message;
+}
+
+ItemType::Ptr ValidationError::type() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "This function should never be called, the caller "
+ "didn't check whether the AtomicValue was an ValidationError.");
+ return ItemType::Ptr();
+}
+
+ReportContext::ErrorCode ValidationError::errorCode() const
+{
+ return m_code;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qvalidationerror_p.h b/src/xmlpatterns/data/qvalidationerror_p.h
new file mode 100644
index 0000000..d93f6cb
--- /dev/null
+++ b/src/xmlpatterns/data/qvalidationerror_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ValidationError_H
+#define Patternist_ValidationError_H
+
+#include "qitem_p.h"
+#include "qreportcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Used for signalling casting errors.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class ValidationError : public AtomicValue
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ValidationError> Ptr;
+
+ /**
+ * Creates a ValidationError instance that represents a type error.
+ *
+ * @param description A detailed description of what that made the cast fail,
+ * if any. If @c null, which QString() creates, a generic message
+ * will be used.
+ */
+ static AtomicValue::Ptr createError(const QString &description = QString(),
+ const ReportContext::ErrorCode = ReportContext::FORG0001);
+
+ /**
+ * A human readable, translated message describing the error.
+ */
+ QString message() const;
+
+ /**
+ * @returns always @c true
+ */
+ virtual bool hasError() const;
+
+ /**
+ * Always results in an assert crash.
+ */
+ virtual ItemType::Ptr type() const;
+
+ /**
+ * Always results in an assert crash.
+ */
+ virtual QString stringValue() const;
+
+ /**
+ * @returns the error code this ValidationError represents. Typically, this
+ * is ReportContext::FORG0001.
+ */
+ ReportContext::ErrorCode errorCode() const;
+
+ protected:
+ ValidationError(const QString &msg, const ReportContext::ErrorCode code);
+
+ const QString m_message;
+ const ReportContext::ErrorCode m_code;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qvaluefactory.cpp b/src/xmlpatterns/data/qvaluefactory.cpp
new file mode 100644
index 0000000..8f7e5a3
--- /dev/null
+++ b/src/xmlpatterns/data/qvaluefactory.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomiccaster_p.h"
+#include "qatomicstring_p.h"
+#include "qcastingplatform_p.h"
+#include "qvaluefactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/**
+ * @short Helper class for ValueFactory::fromLexical() which exposes
+ * CastingPlatform appropriately.
+ *
+ * @relates ValueFactory
+ */
+class PerformValueConstruction : public CastingPlatform<PerformValueConstruction, false>
+ , public SourceLocationReflection
+{
+public:
+ PerformValueConstruction(const SourceLocationReflection *const sourceLocationReflection,
+ const SchemaType::Ptr &toType) : m_sourceReflection(sourceLocationReflection)
+ , m_targetType(AtomicType::Ptr(toType))
+ {
+ Q_ASSERT(m_sourceReflection);
+ }
+
+ AtomicValue::Ptr operator()(const AtomicValue::Ptr &lexicalValue,
+ const SchemaType::Ptr & /*type*/,
+ const ReportContext::Ptr &context)
+ {
+ prepareCasting(context, BuiltinTypes::xsString);
+ return AtomicValue::Ptr(const_cast<AtomicValue *>(cast(lexicalValue, context).asAtomicValue()));
+ }
+
+ const SourceLocationReflection *actualReflection() const
+ {
+ return m_sourceReflection;
+ }
+
+ ItemType::Ptr targetType() const
+ {
+ return m_targetType;
+ }
+
+private:
+ const SourceLocationReflection *const m_sourceReflection;
+ const ItemType::Ptr m_targetType;
+};
+
+AtomicValue::Ptr ValueFactory::fromLexical(const QString &lexicalValue,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection)
+{
+ Q_ASSERT(context);
+ Q_ASSERT(type);
+ Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO,
+ "We can only construct for atomic values.");
+
+ return PerformValueConstruction(sourceLocationReflection, type)(AtomicString::fromValue(lexicalValue),
+ type,
+ context);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qvaluefactory_p.h b/src/xmlpatterns/data/qvaluefactory_p.h
new file mode 100644
index 0000000..e383d27
--- /dev/null
+++ b/src/xmlpatterns/data/qvaluefactory_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ValueFactory_H
+#define Patternist_ValueFactory_H
+
+#include "qitem_p.h"
+#include "qreportcontext_p.h"
+#include "qschematype_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides fromLexical(), which allows instantiation of atomic
+ * values from arbitrary types.
+ *
+ * This class wraps the helper class CastingPlatform with a more specific,
+ * high-level API.
+ *
+ * @see CastingPlatform
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_schema
+ */
+ class ValueFactory
+ {
+ public:
+ /**
+ * @short Returns an AtomicValue of type @p type from the lexical space
+ * @p lexicalValue, and raise an error through @p context if that's
+ * impossible.
+ *
+ * ValueFactory does not take ownership of @p sourceLocationReflection.
+ */
+ static AtomicValue::Ptr fromLexical(const QString &lexicalValue,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection);
+
+ private:
+ Q_DISABLE_COPY(ValueFactory)
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/data/qyearmonthduration.cpp b/src/xmlpatterns/data/qyearmonthduration.cpp
new file mode 100644
index 0000000..5ff60a5
--- /dev/null
+++ b/src/xmlpatterns/data/qyearmonthduration.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonvalues_p.h"
+
+#include "qyearmonthduration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+YearMonthDuration::YearMonthDuration(const bool isPositiveP,
+ const YearProperty yearsP,
+ const MonthProperty monthsP) : AbstractDuration(isPositiveP),
+ m_years(yearsP),
+ m_months(monthsP)
+{
+ Q_ASSERT(monthsP < 32 && monthsP > -32);
+}
+
+YearMonthDuration::Ptr YearMonthDuration::fromLexical(const QString &lexical)
+{
+ static const CaptureTable captureTable(
+ /* The extra paranthesis is a build fix for GCC 3.3. */
+ (QRegExp(QLatin1String(
+ "^\\s*" /* Any preceding whitespace. */
+ "(-)?" /* Sign, if any. */
+ "P" /* Delimiter. */
+ "(?:(\\d+)Y)?" /* The years part. */
+ "(?:(\\d+)M)?" /* The months part. */
+ "\\s*$" /* Any terminating whitespace. */))),
+ 2, /* yearP. */
+ 3 /* monthP. */);
+
+ YearProperty years = 0;
+ MonthProperty months = 0;
+ bool isPos;
+
+ const AtomicValue::Ptr err(create(captureTable, lexical, &isPos, &years,
+ &months, 0, 0, 0, 0, 0));
+
+ return err ? err : YearMonthDuration::Ptr(new YearMonthDuration(isPos, years, months));
+}
+
+YearMonthDuration::Ptr YearMonthDuration::fromComponents(const bool isPositive,
+ const YearProperty years,
+ const MonthProperty months)
+{
+ return YearMonthDuration::Ptr(new YearMonthDuration(isPositive, years, months));
+}
+
+QString YearMonthDuration::stringValue() const
+{
+ QString retval;
+
+ if(!m_isPositive)
+ retval.append(QLatin1Char('-'));
+
+ retval.append(QLatin1Char('P'));
+
+ /* When years == 0 and months == 0, we get "P0M", which
+ * is the correct canonical form. */
+ if(m_years)
+ {
+ retval.append(QString::number(m_years));
+ retval.append(QLatin1Char('Y'));
+
+ if(m_months)
+ {
+ retval.append(QString::number(m_months));
+ retval.append(QLatin1Char('M'));
+ }
+ }
+ else
+ {
+ if(m_months)
+ {
+ retval.append(QString::number(m_months));
+ retval.append(QLatin1Char('M'));
+ }
+ else
+ return QLatin1String("P0M"); /* Ensure the canonical form. */
+ }
+
+ return retval;
+}
+
+AbstractDuration::Value YearMonthDuration::value() const
+{
+ return (m_years * 12 + m_months) * (m_isPositive ? 1 : -1);
+}
+
+Item YearMonthDuration::fromValue(const Value val) const
+{
+ if(val == 0)
+ return toItem(CommonValues::YearMonthDurationZero);
+ else
+ {
+ const Value absValue = qAbs(val);
+ return toItem(YearMonthDuration::fromComponents(val >= 0,
+ absValue / 12,
+ absValue % 12));
+ }
+}
+
+ItemType::Ptr YearMonthDuration::type() const
+{
+ return BuiltinTypes::xsYearMonthDuration;
+}
+
+YearProperty YearMonthDuration::years() const
+{
+ return m_years;
+}
+
+MonthProperty YearMonthDuration::months() const
+{
+ return m_months;
+}
+
+DayCountProperty YearMonthDuration::days() const
+{
+ return 0;
+}
+
+HourProperty YearMonthDuration::hours() const
+{
+ return 0;
+}
+
+MinuteProperty YearMonthDuration::minutes() const
+{
+ return 0;
+}
+
+SecondProperty YearMonthDuration::seconds() const
+{
+ return 0;
+}
+
+MSecondProperty YearMonthDuration::mseconds() const
+{
+ return 0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/data/qyearmonthduration_p.h b/src/xmlpatterns/data/qyearmonthduration_p.h
new file mode 100644
index 0000000..ca53325
--- /dev/null
+++ b/src/xmlpatterns/data/qyearmonthduration_p.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_YearMonthDuration_H
+#define Patternist_YearMonthDuration_H
+
+#include "qabstractduration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of the @c xs:yearMonthDuration type.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class YearMonthDuration : public AbstractDuration
+ {
+ public:
+ typedef AtomicValue::Ptr Ptr;
+
+ /**
+ * Creates an instance from the lexical representation @p string.
+ */
+ static YearMonthDuration::Ptr fromLexical(const QString &string);
+
+ static YearMonthDuration::Ptr fromComponents(const bool isPositive,
+ const YearProperty years,
+ const MonthProperty months);
+
+ virtual ItemType::Ptr type() const;
+ virtual QString stringValue() const;
+
+ /**
+ * @returns the value of this @c xs:yearMonthDuration in months.
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#dt-yearMonthDuration">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 10.3.2.2 Calculating the value of a
+ * xs:dayTimeDuration from the lexical representation</a>
+ */
+ virtual Value value() const;
+
+ /**
+ * If @p val is zero, is CommonValues::YearMonthDurationZero returned.
+ */
+ virtual Item fromValue(const Value val) const;
+
+ /**
+ * @returns the years component. Always positive.
+ */
+ virtual YearProperty years() const;
+
+ /**
+ * @returns the months component. Always positive.
+ */
+ virtual MonthProperty months() const;
+
+ /**
+ * @returns always 0.
+ */
+ virtual DayCountProperty days() const;
+
+ /**
+ * @returns always 0.
+ */
+ virtual HourProperty hours() const;
+
+ /**
+ * @returns always 0.
+ */
+ virtual MinuteProperty minutes() const;
+
+ /**
+ * @returns always 0.
+ */
+ virtual SecondProperty seconds() const;
+
+ /**
+ * @returns always 0.
+ */
+ virtual MSecondProperty mseconds() const;
+
+ protected:
+ friend class CommonValues;
+
+ YearMonthDuration(const bool isPositive,
+ const YearProperty years,
+ const MonthProperty months);
+
+ private:
+ const YearProperty m_years;
+ const MonthProperty m_months;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/documentationGroups.dox b/src/xmlpatterns/documentationGroups.dox
new file mode 100644
index 0000000..d3b1d28
--- /dev/null
+++ b/src/xmlpatterns/documentationGroups.dox
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
+/**
+ * @file
+ * @short Contains Doxygen documentation for groups.
+ */
+
+namespace QPatternist
+{
+ /**
+ * @short The abstract syntax tree nodes that implements the builtin
+ * functions, such as @c fn:concat().
+ *
+ * @defgroup Patternist_functions Function Implementations
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+ /**
+ * @short The abstract syntax tree nodes that is generated for XPath,
+ * XQuery, and XSL-T code.
+ *
+ * XPath's approach of compilation is traditional. An Abstract Syntax
+ * Tree(AST) is built, where the Expression class is the abstract base
+ * class for all kinds of implementations of expressions.
+ *
+ * What perhaps can be said to be characteristic for Patternist is that the
+ * base class, Expression, performs a lot of work, and that sub-classes
+ * declares what specific behaviors they need, which the Expression's
+ * functions then bring into action.
+ *
+ * XPath expressions often have different amount of operands. For example,
+ * the 'and' expression takes two, the context item(".") none, and the
+ * if-expression three. To help expression implementations with that, there
+ * exist the abstract EmptyContainer, SingleContainer, PairContainer,
+ * TripleContainer, and UnlimitedContainer classes for avoiding duplicating
+ * code.
+ *
+ * @defgroup Patternist_expressions Expressions
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+ /**
+ * @short Various classes that contains small utility functions.
+ *
+ * @defgroup Patternist Utility Classes
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+ /**
+ * @short Classes for the type system in the XQuery & XSL-T language.
+ *
+ * @defgroup Patternist_types Type system
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+ /**
+ * @defgroup Patternist_xdm XQuery/XPath Data Model
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+ /**
+ * @short Patternist's family of iterators in one of the most central parts
+ * of Patternist's API, and are responsible for carrying, and typically
+ * also creating, data.
+ *
+ * An iterator, which always is an Iterator sub-class, is similar to a
+ * Java-style iterator. What signifies Patternist's iterators is that they
+ * almost always contains business logic(which is the cause to their
+ * efficiency).
+ *
+ * An example which illustrates this principle is the RangeIterator. When
+ * the RangeExpression is told to create a sequence of integers between 1
+ * and 1000, it doesn't enter a loop that allocates 1000 Integer instances,
+ * but instead return an RangeIterator that incrementally creates the
+ * numbers when asked to do so via its RangeIterator::next() function. If
+ * it turns out that the expression that has the range expression as
+ * operand only needs three items from it, that is what gets created, not
+ * 1000.
+ *
+ * All iterators operates by that principle, perhaps suitably labeled as
+ * "pull-based", "lazy loaded" or "serialized". Central for the XPath
+ * language is that it filters and selects data, and the iterators supports
+ * this well by letting the demand of the filter expressions(the callees)
+ * decide how "much" source that gets computed. In this way the evaluation
+ * of an expression tree can lead to a chain of pipelined iterators, where
+ * the first asks the second for data and then performs its specific
+ * operations, the second subsequently asks the third, and so forth.
+ *
+ * However, the iterators are not limited to be used for representing
+ * sequences of items in the XPath Data Model. The Iterator is
+ * parameterized on one argument, meaning any type of "units" can be
+ * iterated, be it Item or any other. One use of this is in the
+ * ExpressionSequence(which implements the comma operator) where it creates
+ * Iterator instances over Expression instances -- its operands. The
+ * parameterization is often used in combination with the MappingIterator
+ * and the MappingCallback.
+ *
+ * @defgroup Patternist_iterators Iterators
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+}
diff --git a/src/xmlpatterns/environment/createReportContext.sh b/src/xmlpatterns/environment/createReportContext.sh
new file mode 100755
index 0000000..f39e146
--- /dev/null
+++ b/src/xmlpatterns/environment/createReportContext.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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 Technology Preview License Agreement accompanying
+## this package.
+##
+## 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+# Generate ReportContext.h by invoking createReportContext.xsl, which
+# in turns performs a transformation on the specs, fetched from http://www.w3.org/.
+
+target="qreportcontext_p.h"
+tmpFile=".reportContextInput.tmp.xml"
+echo "<dummy/>" > $tmpFile
+p4 revert $target
+p4 edit $target
+xsltproc createReportContext.xsl $tmpFile > $target
+p4 revert -a $target
+rm -f $tmpFile
diff --git a/src/xmlpatterns/environment/createReportContext.xsl b/src/xmlpatterns/environment/createReportContext.xsl
new file mode 100644
index 0000000..ee0b143
--- /dev/null
+++ b/src/xmlpatterns/environment/createReportContext.xsl
@@ -0,0 +1,559 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Patternist project on Qt Labs.
+**
+** $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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+***************************************************************************
+*/
+-->
+
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:h="http://www.w3.org/1999/xhtml"
+ version="1.0">
+
+ <xsl:output omit-xml-declaration="yes"/>
+
+<!--
+This code open the following specifications:
+
+ - XQuery 1.0 and XPath 2.0 Functions and Operators
+ - XML Path Language (XPath) 2.0
+ - XSL Transformations (XSLT) Version 2.0
+ - XQuery 1.0: An XML Query Language
+
+and extracts the error codes as well as their documentation and exports
+them as enum values into a C++ enumerator called ErrorCode.
+
+NOTE: Be aware of binary compatibility when using this stylesheet.
+-->
+
+<!--
+<xsl:variable name="xslt20" select="document('xslt20.html')"/>
+-->
+<xsl:variable name="xslt20" select="document('http://www.w3.org/TR/xslt20')"/>
+
+<!--
+<xsl:variable name="xqfo" select="document('xqfo.html')"/>
+-->
+<xsl:variable name="xqfo" select="document('http://www.w3.org/TR/xpath-functions/')"/>
+
+<!--
+<xsl:variable name="xq" select="document('xq.html')"/>
+-->
+<xsl:variable name="xq" select="document('http://www.w3.org/TR/xquery/')"/>
+
+<!--
+<xsl:variable name="ser" select="document('ser.html')"/>
+-->
+<xsl:variable name="ser" select="document('http://www.w3.org/TR/xslt-xquery-serialization/')"/>
+
+<!--
+*********************************************
+*********************************************
+-->
+<xsl:template match="/"><xsl:text disable-output-escaping="yes"
+><![CDATA[/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ReportContext_H
+#define Patternist_ReportContext_H
+
+#include <QSharedData>
+#include <QAbstractUriResolver>
+#include <QSourceLocation>
+
+#include "qnamepool_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractMessageHandler;
+class QSourceLocation;
+class QString;
+
+namespace QPatternist
+{
+ class SourceLocationReflection;
+
+ /**
+ * @short A callback for reporting errors.
+ *
+ * ReportContext receives messages of various severity and type via its
+ * functions warning() and error(). In turn, ReportContext create Message instances
+ * and submit them to the QAbstractMessageHandler instance returned by messageHandler().
+ *
+ * The Message attributes are set as follows:
+ *
+ * - Message::description() - A translated, human-readable description
+ * - Message::type() - Message::Error if a static, dynamic or type error was encountered
+ * that halted compilation or evaluation, or Message::Warning in case of a warning
+ * - Message::identifier() - This is a URI consisting of the error namespace with the
+ * error code as fragment. For example, a Message representing a syntax error
+ * would return the type "http://www.w3.org/2005/xqt-errors#XPST0003". The convenience
+ * function codeFromURI() can be used to extract the error code. The error namespace
+ * is typically the namespace for XPath and XQuery errors(as in the previous example), but
+ * can also be user defined.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-identifying-errors">XML Path Language
+ * (XPath) 2.0, 2.3.2 Identifying and Reporting Errors</a>
+ * @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 <frans.englich@nokia.com>
+ * @warning This file is auto-generated from extractErrorCodes.xsl. Any
+ * modifications done to this file are lost.
+ */
+ class Q_AUTOTEST_EXPORT ReportContext : public QSharedData
+ {
+ public:
+ typedef QHash<const SourceLocationReflection *, QSourceLocation> LocationHash;
+
+ /**
+ * A smart pointer wrapping ReportContext instances.
+ */
+ typedef QExplicitlySharedDataPointer<ReportContext> Ptr;
+
+ /**
+ * @short Default constructors.
+ *
+ * For some reason GCC fails to synthesize it, so we provide an empty
+ * one here.
+ */
+ inline ReportContext() {}
+
+ virtual ~ReportContext();
+
+ /**
+ * Error codes that corresponds to the error codes defined in the
+ * relevant specifications. They are used throughout the API for
+ * identifying error conditions.
+ *
+ * While strings could have been used for identifying errors, enums
+ * reduces bugs by providing type safety.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#errors">XML
+ * Path Language (XPath) 2.0, 2.3 Error Handling</a>
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#d1e10985">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, C Error Summary</a>
+ * @see <a href="http://www.w3.org/TR/xslt20/#error-summary">XSL Transformations
+ * (XSLT) Version 2.0, E Summary of Error Conditions (Non-Normative)</a>
+ * @note The enumerator values' Doxygen documentation is copied from the
+ * W3C documents
+ * <a href="http://www.w3.org/TR/xpath-functions">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators</a>,
+ * <a href="http://www.w3.org/TR/xpath20">XML Path Language (XPath) 2.0</a>, and
+ * <a href="http://www.w3.org/TR/xslt20/">XSL Transformations (XSLT)
+ * Version 2.0</a>, respectively. The doxygen documentation is therefore covered
+ * by the following legal notice:
+ * "Copyright @ 2005 W3C&reg; (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
+ * <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and
+ * <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document
+ * use</a> rules apply."
+ * @warning This enumerator is auto-generated from the relevant specifications
+ * by the XSL-T stylesheet extractErrorCodes.xsl. Hence, any modifications
+ * done to this file, in contrary to the stylesheet, are therefore lost.
+ */]]></xsl:text>
+ enum ErrorCode
+ {
+ /**
+ * XML Schema error code.
+ */
+ XSDError,
+
+<!-- The order of the calls is significant. The templates takes into account
+ to avoid the last comma(extractXSLT20 does this). -->
+<xsl:call-template name="extractXQuery10"/>
+<xsl:call-template name="extractXQueryFO"/>
+<xsl:call-template name="extractSerialization"/>
+<xsl:call-template name="extractXSLT20"/>
+ };
+<xsl:text disable-output-escaping="yes"><![CDATA[
+ /**
+ * Issues a warning, should not be used excessively. This can
+ * be used to communicate that a certain implementation defined
+ * feature is unsupported or that a certain expression most likely
+ * doesn't do what the users wants, to name a few examples.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#errors">XML Path Language (XPath) 2.0,
+ * 2.3 Error Handling</a>
+ * @param message the message to be read by the user.
+ * @param sourceLocation the location of where the warning originates from.
+ */
+ void warning(const QString &message, const QSourceLocation &sourceLocation = QSourceLocation());
+
+ /**
+ * Issues an error. May be used at the static analysis phase or
+ * the dynamic evaluation phase.
+ *
+ * For SourceLocationReflection instances, the overload taking an SouourceLocationReflection should be used.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#errors">XML Path Language (XPath) 2.0,
+ * 2.3 Error Handling</a>
+ * @param message the message to be read by the user.
+ * @param errorCode identifies the error condition, as described
+ * @param sourceLocation the location of where the error originates from
+ * in "XML Path Language (XPath) 2.0" section "G Error Conditions"
+ */
+ void error(const QString &message,
+ const ReportContext::ErrorCode errorCode,
+ const QSourceLocation &sourceLocation);
+
+ /**
+ * Overload.
+ *
+ * Same as the above, but passes the SourceLocationReflection as reference for error reporting.
+ */
+ void error(const QString &message,
+ const ReportContext::ErrorCode errorCode,
+ const SourceLocationReflection *reflection);
+
+ /**
+ * Issues an error which is not identified in the XPath specifications. This function
+ * is among other things used for implementing the <tt>fn:error()</tt> function.
+ */
+ void error(const QString &message,
+ const QXmlName qName,
+ const SourceLocationReflection *const r);
+
+ /**
+ * @return the QAbstractMessageHandler which functions such as warning() and
+ * error() should submit messages to. This function
+ * may never return @c null; a valid QAbstractMessageHandler pointer must always be returned.
+ */
+ virtual QAbstractMessageHandler *messageHandler() const = 0;
+
+ virtual NamePool::Ptr namePool() const = 0;
+
+ /**
+ * Returns a string representation of the error code @p code.
+ *
+ * @see ReportContext::ErrorCode
+ * @param errorCode identifies the error condition, as described
+ * in <a href="http://www.w3.org/TR/xpath20/#id-errors">XML Path
+ * Language (XPath) 2.0, G Error Conditions</a>
+ */
+ static QString codeToString(const ReportContext::ErrorCode errorCode);
+
+ /**
+ * @returns the error code part of @p typeURI and sets @p uri to the error namespace. Note
+ * that the error namespace not necessarily is the namespace for XPath and
+ * XQuery errors, http://www.w3.org/2005/xqt-errors, but can be user defined.
+ */
+ static QString codeFromURI(const QString &typeURI,
+ QString &uri);
+
+ /**
+ * @short Returns the source location applying for @p reflection.
+ */
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const = 0;
+
+ /**
+ * Resolves @p relative against @p baseURI, possibly using a URI resolver.
+ */
+ QUrl resolveURI(const QUrl &relative,
+ const QUrl &baseURI) const;
+
+ /**
+ * @short The URI resolver in use.
+ *
+ * If no URI resolver is in use, a @c null pointer is returned.
+ *
+ * @note You should probably use resolveURI(), which handles the case of
+ * when uriResolver() is @c null.
+ */
+ virtual QAbstractUriResolver *uriResolver() const = 0;
+
+ private:
+ void createError(const QString &description,
+ const QtMsgType type,
+ const QUrl &id,
+ const QSourceLocation &sourceLocation) const;
+ static inline QString finalizeDescription(const QString &desc);
+ QSourceLocation lookupSourceLocation(const SourceLocationReflection *const ref) const;
+
+ Q_DISABLE_COPY(ReportContext)
+ };
+
+ /**
+ * @short This is the class type that is being thrown when a query error occur.
+ *
+ * @relates ReportContext
+ */
+ typedef bool Exception;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif]]></xsl:text>
+</xsl:template>
+<!--
+*********************************************
+*********************************************
+-->
+
+
+
+
+<!--
+*********************************************
+XQuery 1.0 and XPath 2.0 Functions and Operators
+*********************************************
+-->
+<xsl:template name="extractXQueryFO">
+ <xsl:apply-templates mode="xqfo" select="$xqfo/h:html/h:body/h:div[@class = 'back']//
+ h:div[h:h2/h:a/@id = 'error-summary']/h:dl/h:dt"/>
+</xsl:template>
+
+<xsl:template mode="xqfo" match="h:dt">
+ /**<xsl:call-template name="formatDocs">
+ <xsl:with-param name="content" select="substring(., 15)"/>
+ </xsl:call-template>
+ */
+ <xsl:value-of select="substring(h:a/@name, 4)"/>,
+</xsl:template>
+<!--
+*********************************************
+*********************************************
+-->
+
+
+
+
+<!--
+*********************************************
+XQuery 1.0: An XML Query Language
+*********************************************
+-->
+<xsl:template name="extractXQuery10">
+ <xsl:apply-templates mode="xquery10" select="$xq/h:html/h:body/h:div[@class = 'back']//
+ h:div[h:h2/h:a/@id = 'id-errors']/h:dl/h:dt"/>
+</xsl:template>
+
+<xsl:template mode="xquery10" match="h:dt">
+ /**<xsl:call-template name="formatDocs">
+ <xsl:with-param name="content" select="following-sibling::h:dd/h:p"/>
+ </xsl:call-template>
+ */
+ <xsl:value-of select="substring(., 5)"/>,
+</xsl:template>
+<!--
+*********************************************
+*********************************************
+-->
+
+
+
+<!--
+*********************************************
+XSL Transformations (XSLT) Version 2.0
+*********************************************
+-->
+<xsl:template name="extractXSLT20">
+ <xsl:apply-templates mode="xslt20" select="$xslt20/h:html/h:body/h:div[@class = 'back']//
+ h:div[@class = 'div1' and h:h2/h:a/@id = 'error-summary']/h:dl/h:dt"/>
+</xsl:template>
+
+<xsl:template mode="xslt20" match="h:dt">
+ /**<xsl:call-template name="formatDocs">
+ <xsl:with-param name="content" select="following-sibling::h:dd/h:p"/>
+ </xsl:call-template>
+ */
+ <xsl:value-of select="normalize-space(substring(h:a/h:span, 4))"/>
+
+ <xsl:if test="position() != last()">,</xsl:if>
+ <xsl:text>&#xa;</xsl:text>
+</xsl:template>
+<!--
+*********************************************
+*********************************************
+-->
+
+
+
+<!--
+*********************************************
+XSLT 2.0 and XQuery 1.0 Serialization
+*********************************************
+-->
+<xsl:template name="extractSerialization">
+ <xsl:apply-templates mode="ser" select="$ser/h:html/h:body/h:div[@class = 'back']//
+ h:div[@class = 'div1' and h:h2/h:a/@id = 'id-errors']/h:dl/h:dt"/>
+</xsl:template>
+
+<xsl:template mode="ser" match="h:dt">
+ /**<xsl:call-template name="formatDocs">
+ <xsl:with-param name="content" select="following-sibling::h:dd/h:p"/>
+ </xsl:call-template>
+ */
+ <xsl:value-of select="substring(., 5)"/>,
+</xsl:template>
+<!--
+*********************************************
+*********************************************
+-->
+
+
+
+
+<!-- Random stuff -->
+<xsl:template name="formatDocs">
+ <xsl:param name="content"/>
+
+ <xsl:call-template name="internalFormatDocs">
+ <xsl:with-param name="content">
+ <!-- Escape # in order to keep Doxygen happy. -->
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="translate(normalize-space($content), '&#xA0;', '')"/>
+ <xsl:with-param name="from" select="' #'"/>
+ <xsl:with-param name="to" select="' \#'"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+
+</xsl:template>
+
+<xsl:template name="internalFormatDocs">
+ <xsl:param name="content"/>
+
+ <xsl:variable name="nextText" select="substring($content, 61)"/>
+ <xsl:variable name="afterSpace" select="substring-after($nextText, ' ')"/>
+ * <xsl:value-of select="substring($content, 1, 60)"/>
+ <xsl:value-of select="substring-before($nextText, ' ')"/>
+ <xsl:choose>
+ <xsl:when test="string-length($afterSpace) = 0"><xsl:value-of select="$nextText"/>
+ </xsl:when>
+ <xsl:when test="string-length($afterSpace) &lt; 60">
+ * <xsl:value-of select="$afterSpace"/>
+ </xsl:when>
+ <xsl:when test="string-length($nextText)">
+ <xsl:call-template name="formatDocs">
+ <xsl:with-param name="content"
+ select="$afterSpace"/>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!--
+ reusable replace-string function
+ http://aspn.activestate.com/ASPN/Cookbook/XSLT/Recipe/65426
+ -->
+ <xsl:template name="replace-string">
+ <xsl:param name="text"/>
+ <xsl:param name="from"/>
+ <xsl:param name="to"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($text, $from)">
+
+ <xsl:variable name="before" select="substring-before($text, $from)"/>
+ <xsl:variable name="after" select="substring-after($text, $from)"/>
+
+ <xsl:value-of select="$before"/>
+ <xsl:value-of select="$to"/>
+
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="$after"/>
+ <xsl:with-param name="from" select="$from"/>
+ <xsl:with-param name="to" select="$to"/>
+ </xsl:call-template>
+
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
+<!-- vim: et:ts=4:sw=4:sts=4
+-->
diff --git a/src/xmlpatterns/environment/environment.pri b/src/xmlpatterns/environment/environment.pri
new file mode 100644
index 0000000..b8a2b65
--- /dev/null
+++ b/src/xmlpatterns/environment/environment.pri
@@ -0,0 +1,32 @@
+HEADERS += $$PWD/qcurrentitemcontext_p.h \
+ $$PWD/qdelegatingdynamiccontext_p.h \
+ $$PWD/qdelegatingstaticcontext_p.h \
+ $$PWD/qdynamiccontext_p.h \
+ $$PWD/qfocus_p.h \
+ $$PWD/qgenericdynamiccontext_p.h \
+ $$PWD/qgenericstaticcontext_p.h \
+ $$PWD/qreceiverdynamiccontext_p.h \
+ $$PWD/qreportcontext_p.h \
+ $$PWD/qstackcontextbase_p.h \
+ $$PWD/qstaticbaseuricontext_p.h \
+ $$PWD/qstaticcontext_p.h \
+ $$PWD/qstaticcurrentcontext_p.h \
+ $$PWD/qstaticfocuscontext_p.h \
+ $$PWD/qstaticcompatibilitycontext_p.h \
+ $$PWD/qstaticnamespacecontext_p.h
+
+SOURCES += $$PWD/qcurrentitemcontext.cpp \
+ $$PWD/qdelegatingdynamiccontext.cpp \
+ $$PWD/qdelegatingstaticcontext.cpp \
+ $$PWD/qdynamiccontext.cpp \
+ $$PWD/qfocus.cpp \
+ $$PWD/qgenericdynamiccontext.cpp \
+ $$PWD/qgenericstaticcontext.cpp \
+ $$PWD/qreceiverdynamiccontext.cpp \
+ $$PWD/qreportcontext.cpp \
+ $$PWD/qstaticbaseuricontext.cpp \
+ $$PWD/qstaticcontext.cpp \
+ $$PWD/qstaticcurrentcontext.cpp \
+ $$PWD/qstaticfocuscontext.cpp \
+ $$PWD/qstaticcompatibilitycontext.cpp \
+ $$PWD/qstaticnamespacecontext.cpp
diff --git a/src/xmlpatterns/environment/qcurrentitemcontext.cpp b/src/xmlpatterns/environment/qcurrentitemcontext.cpp
new file mode 100644
index 0000000..0924d08
--- /dev/null
+++ b/src/xmlpatterns/environment/qcurrentitemcontext.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdaytimeduration_p.h"
+
+#include "qcurrentitemcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CurrentItemContext::CurrentItemContext(const Item &item,
+ const DynamicContext::Ptr &prevContext) : DelegatingDynamicContext(prevContext)
+ , m_currentItem(item)
+{
+ Q_ASSERT(prevContext);
+}
+
+Item CurrentItemContext::currentItem() const
+{
+ return m_currentItem;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qcurrentitemcontext_p.h b/src/xmlpatterns/environment/qcurrentitemcontext_p.h
new file mode 100644
index 0000000..894dde3
--- /dev/null
+++ b/src/xmlpatterns/environment/qcurrentitemcontext_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CurrentItemContext_H
+#define Patternist_CurrentItemContext_H
+
+#include "qdelegatingdynamiccontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A DynamicContext that maintains the focus, a sequence
+ * of items.
+ *
+ * CurrentItemContext implements both the outer and inner focus. The focus is one of
+ * the things that characterizes the XPath language. The focus is what's
+ * iterated over in a predicate, whose current item can be received
+ * via the context item expression, <tt>.</tt>(the dot),
+ * and whose size is retrievable via the function <tt>fn:last()</tt>.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class CurrentItemContext : public DelegatingDynamicContext
+ {
+ public:
+ CurrentItemContext(const Item &item,
+ const DynamicContext::Ptr &prevContext);
+
+ virtual Item currentItem() const;
+
+ private:
+ const Item m_currentItem;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp b/src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp
new file mode 100644
index 0000000..4cf6bac
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDateTime>
+
+#include "qdaytimeduration_p.h"
+#include "qtemplatemode_p.h"
+
+#include "qdelegatingdynamiccontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DelegatingDynamicContext::DelegatingDynamicContext(const DynamicContext::Ptr &prevContext)
+ : m_prevContext(prevContext)
+{
+ Q_ASSERT(m_prevContext);
+}
+
+ItemCacheCell &DelegatingDynamicContext::itemCacheCell(const VariableSlotID slot)
+{
+ return m_prevContext->itemCacheCell(slot);
+}
+
+ItemSequenceCacheCell::Vector &DelegatingDynamicContext::itemSequenceCacheCells(const VariableSlotID slot)
+{
+ return m_prevContext->itemSequenceCacheCells(slot);
+}
+
+xsInteger DelegatingDynamicContext::contextPosition() const
+{
+ return m_prevContext->contextPosition();
+}
+
+Item DelegatingDynamicContext::contextItem() const
+{
+ return m_prevContext->contextItem();
+}
+
+xsInteger DelegatingDynamicContext::contextSize()
+{
+ return m_prevContext->contextSize();
+}
+
+void DelegatingDynamicContext::setFocusIterator(const Item::Iterator::Ptr &it)
+{
+ m_prevContext->setFocusIterator(it);
+}
+
+Item::Iterator::Ptr DelegatingDynamicContext::positionIterator(const VariableSlotID slot) const
+{
+ return m_prevContext->positionIterator(slot);
+}
+
+void DelegatingDynamicContext::setPositionIterator(const VariableSlotID slot,
+ const Item::Iterator::Ptr &newValue)
+{
+ m_prevContext->setPositionIterator(slot, newValue);
+}
+
+void DelegatingDynamicContext::setRangeVariable(const VariableSlotID slotNumber,
+ const Item &newValue)
+{
+ m_prevContext->setRangeVariable(slotNumber, newValue);
+}
+
+Item::Iterator::Ptr DelegatingDynamicContext::focusIterator() const
+{
+ return m_prevContext->focusIterator();
+}
+
+Item DelegatingDynamicContext::rangeVariable(const VariableSlotID slotNumber) const
+{
+ return m_prevContext->rangeVariable(slotNumber);
+}
+
+void DelegatingDynamicContext::setExpressionVariable(const VariableSlotID slotNumber,
+ const Expression::Ptr &newValue)
+{
+ m_prevContext->setExpressionVariable(slotNumber, newValue);
+}
+
+Expression::Ptr DelegatingDynamicContext::expressionVariable(const VariableSlotID slotNumber) const
+{
+ return m_prevContext->expressionVariable(slotNumber);
+}
+
+QAbstractMessageHandler * DelegatingDynamicContext::messageHandler() const
+{
+ return m_prevContext->messageHandler();
+}
+
+QExplicitlySharedDataPointer<DayTimeDuration> DelegatingDynamicContext::implicitTimezone() const
+{
+ return m_prevContext->implicitTimezone();
+}
+
+QDateTime DelegatingDynamicContext::currentDateTime() const
+{
+ return m_prevContext->currentDateTime();
+}
+
+QAbstractXmlReceiver *DelegatingDynamicContext::outputReceiver() const
+{
+ return m_prevContext->outputReceiver();
+}
+
+NodeBuilder::Ptr DelegatingDynamicContext::nodeBuilder(const QUrl &baseURI) const
+{
+ return m_prevContext->nodeBuilder(baseURI);
+}
+
+ResourceLoader::Ptr DelegatingDynamicContext::resourceLoader() const
+{
+ return m_prevContext->resourceLoader();
+}
+
+ExternalVariableLoader::Ptr DelegatingDynamicContext::externalVariableLoader() const
+{
+ return m_prevContext->externalVariableLoader();
+}
+
+NamePool::Ptr DelegatingDynamicContext::namePool() const
+{
+ return m_prevContext->namePool();
+}
+
+QSourceLocation DelegatingDynamicContext::locationFor(const SourceLocationReflection *const reflection) const
+{
+ return m_prevContext->locationFor(reflection);
+}
+
+void DelegatingDynamicContext::addNodeModel(const QAbstractXmlNodeModel::Ptr &nm)
+{
+ m_prevContext->addNodeModel(nm);
+}
+
+const QAbstractUriResolver *DelegatingDynamicContext::uriResolver() const
+{
+ return m_prevContext->uriResolver();
+}
+
+ItemCacheCell &DelegatingDynamicContext::globalItemCacheCell(const VariableSlotID slot)
+{
+ return m_prevContext->globalItemCacheCell(slot);
+}
+
+ItemSequenceCacheCell::Vector &DelegatingDynamicContext::globalItemSequenceCacheCells(const VariableSlotID slot)
+{
+ return m_prevContext->globalItemSequenceCacheCells(slot);
+}
+
+Item DelegatingDynamicContext::currentItem() const
+{
+ return m_prevContext->currentItem();
+}
+
+DynamicContext::TemplateParameterHash &DelegatingDynamicContext::templateParameterStore()
+{
+ return m_prevContext->templateParameterStore();
+}
+
+DynamicContext::Ptr DelegatingDynamicContext::previousContext() const
+{
+ return m_prevContext;
+}
+
+QExplicitlySharedDataPointer<TemplateMode> DelegatingDynamicContext::currentTemplateMode() const
+{
+ return m_prevContext->currentTemplateMode();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h b/src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h
new file mode 100644
index 0000000..552ef7c
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DelegatingDynamicContext_H
+#define Patternist_DelegatingDynamicContext_H
+
+#include "qdynamiccontext_p.h"
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for dynamic contexts that are
+ * created from an existing one.
+ *
+ * In some cases multiple DynamicContext instances must be used in
+ * order to maintain somekind of scope. This class delegates
+ * the DynamicContext interface onto another DynamicContext instance,
+ * allowing the sub-class to only implement what it needs to.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DelegatingDynamicContext : public DynamicContext
+ {
+ public:
+ virtual xsInteger contextPosition() const;
+ virtual Item contextItem() const;
+ virtual xsInteger contextSize();
+
+ virtual ItemCacheCell &itemCacheCell(const VariableSlotID slot);
+ virtual ItemSequenceCacheCell::Vector &itemSequenceCacheCells(const VariableSlotID slot);
+
+ virtual void setRangeVariable(const VariableSlotID slotNumber,
+ const Item &newValue);
+ virtual Item rangeVariable(const VariableSlotID slotNumber) const;
+
+ virtual void setExpressionVariable(const VariableSlotID slotNumber,
+ const Expression::Ptr &newValue);
+ virtual Expression::Ptr expressionVariable(const VariableSlotID slotNumber) const;
+
+ virtual void setFocusIterator(const Item::Iterator::Ptr &it);
+ virtual Item::Iterator::Ptr focusIterator() const;
+
+ virtual Item::Iterator::Ptr positionIterator(const VariableSlotID slot) const;
+ virtual void setPositionIterator(const VariableSlotID slot,
+ const Item::Iterator::Ptr &newValue);
+
+ virtual QAbstractMessageHandler * messageHandler() const;
+ virtual QExplicitlySharedDataPointer<DayTimeDuration> implicitTimezone() const;
+ virtual QDateTime currentDateTime() const;
+ virtual QAbstractXmlReceiver *outputReceiver() const;
+ virtual NodeBuilder::Ptr nodeBuilder(const QUrl &baseURI) const;
+ virtual ResourceLoader::Ptr resourceLoader() const;
+ virtual ExternalVariableLoader::Ptr externalVariableLoader() const;
+ virtual NamePool::Ptr namePool() const;
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const;
+ virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nm);
+ virtual const QAbstractUriResolver *uriResolver() const;
+ virtual ItemCacheCell &globalItemCacheCell(const VariableSlotID slot);
+ virtual ItemSequenceCacheCell::Vector &globalItemSequenceCacheCells(const VariableSlotID slot);
+ virtual Item currentItem() const;
+ virtual TemplateParameterHash &templateParameterStore();
+
+ virtual DynamicContext::Ptr previousContext() const;
+ virtual QExplicitlySharedDataPointer<TemplateMode> currentTemplateMode() const;
+
+ protected:
+ DelegatingDynamicContext(const DynamicContext::Ptr &prevContext);
+
+ const DynamicContext::Ptr m_prevContext;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qdelegatingstaticcontext.cpp b/src/xmlpatterns/environment/qdelegatingstaticcontext.cpp
new file mode 100644
index 0000000..6ad183e
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingstaticcontext.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* Patternist */
+#include "qbasictypesfactory_p.h"
+#include "qfunctionfactorycollection_p.h"
+#include "qgenericnamespaceresolver_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qgenericdynamiccontext_p.h"
+
+#include "qstaticfocuscontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DelegatingStaticContext::DelegatingStaticContext(const StaticContext::Ptr &context) : m_context(context)
+{
+ Q_ASSERT(context);
+}
+
+NamespaceResolver::Ptr DelegatingStaticContext::namespaceBindings() const
+{
+ return m_context->namespaceBindings();
+}
+
+FunctionFactory::Ptr DelegatingStaticContext::functionSignatures() const
+{
+ return m_context->functionSignatures();
+}
+
+DynamicContext::Ptr DelegatingStaticContext::dynamicContext() const
+{
+ return m_context->dynamicContext();
+}
+
+SchemaTypeFactory::Ptr DelegatingStaticContext::schemaDefinitions() const
+{
+ return m_context->schemaDefinitions();
+}
+
+QUrl DelegatingStaticContext::baseURI() const
+{
+ return m_context->baseURI();
+}
+
+void DelegatingStaticContext::setBaseURI(const QUrl &uri)
+{
+ m_context->setBaseURI(uri);
+}
+
+bool DelegatingStaticContext::compatModeEnabled() const
+{
+ return m_context->compatModeEnabled();
+}
+
+QUrl DelegatingStaticContext::defaultCollation() const
+{
+ return m_context->defaultCollation();
+}
+
+QAbstractMessageHandler * DelegatingStaticContext::messageHandler() const
+{
+ return m_context->messageHandler();
+}
+
+void DelegatingStaticContext::setDefaultCollation(const QUrl &uri)
+{
+ m_context->setDefaultCollation(uri);
+}
+
+void DelegatingStaticContext::setNamespaceBindings(const NamespaceResolver::Ptr &resolver)
+{
+ m_context->setNamespaceBindings(resolver);
+}
+
+StaticContext::BoundarySpacePolicy DelegatingStaticContext::boundarySpacePolicy() const
+{
+ return m_context->boundarySpacePolicy();
+}
+
+void DelegatingStaticContext::setBoundarySpacePolicy(const BoundarySpacePolicy policy)
+{
+ m_context->setBoundarySpacePolicy(policy);
+}
+
+StaticContext::ConstructionMode DelegatingStaticContext::constructionMode() const
+{
+ return m_context->constructionMode();
+}
+
+void DelegatingStaticContext::setConstructionMode(const ConstructionMode mode)
+{
+ m_context->setConstructionMode(mode);
+}
+
+StaticContext::OrderingMode DelegatingStaticContext::orderingMode() const
+{
+ return m_context->orderingMode();
+}
+
+void DelegatingStaticContext::setOrderingMode(const OrderingMode mode)
+{
+ m_context->setOrderingMode(mode);
+}
+
+StaticContext::OrderingEmptySequence DelegatingStaticContext::orderingEmptySequence() const
+{
+ return m_context->orderingEmptySequence();
+}
+
+void DelegatingStaticContext::setOrderingEmptySequence(const OrderingEmptySequence ordering)
+{
+ m_context->setOrderingEmptySequence(ordering);
+}
+
+QString DelegatingStaticContext::defaultFunctionNamespace() const
+{
+ return m_context->defaultFunctionNamespace();
+}
+
+void DelegatingStaticContext::setDefaultFunctionNamespace(const QString &ns)
+{
+ m_context->setDefaultFunctionNamespace(ns);
+}
+
+QString DelegatingStaticContext::defaultElementNamespace() const
+{
+ return m_context->defaultElementNamespace();
+}
+
+void DelegatingStaticContext::setDefaultElementNamespace(const QString &ns)
+{
+ m_context->setDefaultElementNamespace(ns);
+}
+
+StaticContext::InheritMode DelegatingStaticContext::inheritMode() const
+{
+ return m_context->inheritMode();
+}
+
+void DelegatingStaticContext::setInheritMode(const InheritMode mode)
+{
+ m_context->setInheritMode(mode);
+}
+
+StaticContext::PreserveMode DelegatingStaticContext::preserveMode() const
+{
+ return m_context->preserveMode();
+}
+
+void DelegatingStaticContext::setPreserveMode(const PreserveMode mode)
+{
+ m_context->setPreserveMode(mode);
+}
+
+ItemType::Ptr DelegatingStaticContext::contextItemType() const
+{
+ return m_context->contextItemType();
+}
+
+ItemType::Ptr DelegatingStaticContext::currentItemType() const
+{
+ return m_context->currentItemType();
+}
+
+ExternalVariableLoader::Ptr DelegatingStaticContext::externalVariableLoader() const
+{
+ return m_context->externalVariableLoader();
+}
+
+StaticContext::Ptr DelegatingStaticContext::copy() const
+{
+ return StaticContext::Ptr(new DelegatingStaticContext(m_context->copy()));
+}
+
+ResourceLoader::Ptr DelegatingStaticContext::resourceLoader() const
+{
+ return m_context->resourceLoader();
+}
+
+NamePool::Ptr DelegatingStaticContext::namePool() const
+{
+ return m_context->namePool();
+}
+
+void DelegatingStaticContext::addLocation(const SourceLocationReflection *const reflection,
+ const QSourceLocation &location)
+{
+ m_context->addLocation(reflection, location);
+}
+
+StaticContext::LocationHash DelegatingStaticContext::sourceLocations() const
+{
+ return m_context->sourceLocations();
+}
+
+QSourceLocation DelegatingStaticContext::locationFor(const SourceLocationReflection *const reflection) const
+{
+ return m_context->locationFor(reflection);
+}
+
+const QAbstractUriResolver *DelegatingStaticContext::uriResolver() const
+{
+ return m_context->uriResolver();
+}
+
+VariableSlotID DelegatingStaticContext::currentRangeSlot() const
+{
+ return m_context->currentRangeSlot();
+}
+
+VariableSlotID DelegatingStaticContext::allocateRangeSlot()
+{
+ return m_context->allocateRangeSlot();
+}
+
+void DelegatingStaticContext::setCompatModeEnabled(const bool newVal)
+{
+ m_context->setCompatModeEnabled(newVal);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qdelegatingstaticcontext_p.h b/src/xmlpatterns/environment/qdelegatingstaticcontext_p.h
new file mode 100644
index 0000000..c34c994
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingstaticcontext_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DelegatingStaticContext_H
+#define Patternist_DelegatingStaticContext_H
+
+#include <QUrl>
+
+#include "qstaticcontext_p.h"
+#include "qfunctionfactory_p.h"
+#include "qschematypefactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Delegates all members to a second instance. Used for
+ * sub-classing.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT DelegatingStaticContext : public StaticContext
+ {
+ public:
+ virtual NamespaceResolver::Ptr namespaceBindings() const;
+ virtual void setNamespaceBindings(const NamespaceResolver::Ptr &);
+
+ virtual FunctionFactory::Ptr functionSignatures() const;
+ virtual SchemaTypeFactory::Ptr schemaDefinitions() const;
+ virtual DynamicContext::Ptr dynamicContext() const;
+
+ virtual QUrl baseURI() const;
+ virtual void setBaseURI(const QUrl &uri);
+
+ virtual bool compatModeEnabled() const;
+ virtual void setCompatModeEnabled(const bool newVal);
+
+ virtual QUrl defaultCollation() const;
+
+ virtual QAbstractMessageHandler * messageHandler() const;
+
+ virtual void setDefaultCollation(const QUrl &uri);
+
+ virtual BoundarySpacePolicy boundarySpacePolicy() const;
+ virtual void setBoundarySpacePolicy(const BoundarySpacePolicy policy);
+
+ virtual ConstructionMode constructionMode() const;
+ virtual void setConstructionMode(const ConstructionMode mode);
+
+ virtual OrderingMode orderingMode() const;
+ virtual void setOrderingMode(const OrderingMode mode);
+ virtual OrderingEmptySequence orderingEmptySequence() const;
+ virtual void setOrderingEmptySequence(const OrderingEmptySequence ordering);
+
+ virtual QString defaultFunctionNamespace() const;
+ virtual void setDefaultFunctionNamespace(const QString &ns);
+
+ virtual QString defaultElementNamespace() const;
+ virtual void setDefaultElementNamespace(const QString &ns);
+
+ virtual InheritMode inheritMode() const;
+ virtual void setInheritMode(const InheritMode mode);
+
+ virtual PreserveMode preserveMode() const;
+ virtual void setPreserveMode(const PreserveMode mode);
+
+ virtual ItemType::Ptr contextItemType() const;
+ virtual ItemType::Ptr currentItemType() const;
+
+ virtual StaticContext::Ptr copy() const;
+
+ virtual ExternalVariableLoader::Ptr externalVariableLoader() const;
+ virtual ResourceLoader::Ptr resourceLoader() const;
+ virtual NamePool::Ptr namePool() const;
+ virtual void addLocation(const SourceLocationReflection *const reflection,
+ const QSourceLocation &location);
+ virtual LocationHash sourceLocations() const;
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const;
+ virtual const QAbstractUriResolver *uriResolver() const;
+
+ virtual VariableSlotID currentRangeSlot() const;
+ virtual VariableSlotID allocateRangeSlot();
+
+ protected:
+ DelegatingStaticContext(const StaticContext::Ptr &context);
+
+ private:
+ const StaticContext::Ptr m_context;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qdynamiccontext.cpp b/src/xmlpatterns/environment/qdynamiccontext.cpp
new file mode 100644
index 0000000..ace8d53
--- /dev/null
+++ b/src/xmlpatterns/environment/qdynamiccontext.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfocus_p.h"
+#include "qreceiverdynamiccontext_p.h"
+#include "qstackcontextbase_p.h"
+
+#include "qdynamiccontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DynamicContext::Ptr DynamicContext::createFocus()
+{
+ return Ptr(new Focus(Ptr(this)));
+}
+
+DynamicContext::Ptr DynamicContext::createStack()
+{
+ return Ptr(new StackContext(Ptr(this)));
+}
+
+DynamicContext::Ptr DynamicContext::createReceiverContext(QAbstractXmlReceiver *const receiver)
+{
+ Q_ASSERT(receiver);
+ return Ptr(new ReceiverDynamicContext(Ptr(this), receiver));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qdynamiccontext_p.h b/src/xmlpatterns/environment/qdynamiccontext_p.h
new file mode 100644
index 0000000..131ce54
--- /dev/null
+++ b/src/xmlpatterns/environment/qdynamiccontext_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DynamicContext_H
+#define Patternist_DynamicContext_H
+
+#include "qautoptr_p.h"
+#include "qcachecells_p.h"
+#include "qexternalvariableloader_p.h"
+#include "qitem_p.h"
+#include "qnamepool_p.h"
+#include "qnodebuilder_p.h"
+#include "qprimitives_p.h"
+#include "qreportcontext_p.h"
+#include "qresourceloader_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDateTime;
+template<typename T> class QVector;
+
+namespace QPatternist
+{
+ class DayTimeDuration;
+ class Expression;
+ class TemplateMode;
+
+ /**
+ * @short Carries information and facilities used at runtime, and hence
+ * provides a state for that stage in a thread-safe manner.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#eval_context">XQuery
+ * 1.0: An XML Query Language, 2.1.2 Dynamic Context</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#id-dynamic-evaluation">XQuery
+ * 1.0: An XML Query Language, 2.2.3.2 Dynamic Evaluation Phase</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DynamicContext : public ReportContext
+ {
+ public:
+ /**
+ * @short Carries template parameters at runtime.
+ *
+ * The key is the name of the parameter, and the value the Expression
+ * which supplies the value.
+ */
+ typedef QHash<QXmlName, QExplicitlySharedDataPointer<Expression> > TemplateParameterHash;
+ typedef QExplicitlySharedDataPointer<DynamicContext> Ptr;
+
+ virtual ~DynamicContext()
+ {
+ }
+
+ /**
+ * This function intentionally returns by reference.
+ *
+ * @see globalItemCacheCell()
+ */
+ virtual ItemCacheCell &itemCacheCell(const VariableSlotID slot) = 0;
+
+ /**
+ * This function intentionally returns by reference.
+ *
+ * @see globalItemSequenceCacheCells
+ */
+ virtual ItemSequenceCacheCell::Vector &itemSequenceCacheCells(const VariableSlotID slot) = 0;
+
+ virtual xsInteger contextPosition() const = 0;
+ virtual Item contextItem() const = 0;
+ virtual xsInteger contextSize() = 0;
+
+ virtual void setRangeVariable(const VariableSlotID slot,
+ const Item &newValue) = 0;
+ virtual Item rangeVariable(const VariableSlotID slot) const = 0;
+ virtual void setExpressionVariable(const VariableSlotID slot,
+ const QExplicitlySharedDataPointer<Expression> &newValue) = 0;
+ virtual QExplicitlySharedDataPointer<Expression>
+ expressionVariable(const VariableSlotID slot) const = 0;
+
+ virtual Item::Iterator::Ptr positionIterator(const VariableSlotID slot) const = 0;
+ virtual void setPositionIterator(const VariableSlotID slot,
+ const Item::Iterator::Ptr &newValue) = 0;
+
+ virtual void setFocusIterator(const Item::Iterator::Ptr &it) = 0;
+ virtual Item::Iterator::Ptr focusIterator() const = 0;
+
+ virtual QExplicitlySharedDataPointer<DayTimeDuration> implicitTimezone() const = 0;
+ virtual QDateTime currentDateTime() const = 0;
+
+ virtual QAbstractXmlReceiver *outputReceiver() const = 0;
+ virtual NodeBuilder::Ptr nodeBuilder(const QUrl &baseURI) const = 0;
+ virtual ResourceLoader::Ptr resourceLoader() const = 0;
+ virtual ExternalVariableLoader::Ptr externalVariableLoader() const = 0;
+ virtual NamePool::Ptr namePool() const = 0;
+
+ /**
+ * @short Returns the item that @c fn:current() returns.
+ *
+ * Hence, this is not the focus, and very different from the focus.
+ *
+ * @see CurrentItemStore
+ * @see CurrentFN
+ */
+ virtual Item currentItem() const = 0;
+
+ DynamicContext::Ptr createFocus();
+ DynamicContext::Ptr createStack();
+ DynamicContext::Ptr createReceiverContext(QAbstractXmlReceiver *const receiver);
+
+ /**
+ * Whenever a tree gets built, this function is called. DynamicContext
+ * has the responsibility of keeping a copy of @p nm, such that it
+ * doesn't go out of scope, since no one else will reference @p nm.
+ *
+ * I think this is currently only used for temporary node trees. In
+ * other cases they are stored in the ExternalResourceLoader.
+ *
+ * The caller guarantees that @p nm is not @c null.
+ */
+ virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nm) = 0;
+
+ /**
+ * Same as itemCacheCell(), but is only used for global varibles. This
+ * is needed because sometimes stack frames needs to be created for
+ * other kinds of variables(such as in the case of user function
+ * calls), while the global variable(s) needs to continue to use the
+ * same cache, instead of one for each new stack frame, typically an
+ * instance of StackContextBase.
+ *
+ * This has two effects:
+ *
+ * - It's an optimization. Instead of that a global variable gets evaluated each
+ * time a user function is called, think recursive functions, it's done
+ * only once.
+ * - Query stability, hence affects things like node identity and
+ * therefore conformance. Hence affects for instance what nodes a query
+ * returns, since node identity affect node deduplication.
+ */
+ virtual ItemCacheCell &globalItemCacheCell(const VariableSlotID slot) = 0;
+
+ /**
+ * @short When a template is called, this member carries the template
+ * parameters.
+ *
+ * Hence this is similar to the other variable stack functions such as
+ * rangeVariable() and expressionVariable(), the difference being that
+ * the order of template parameters as well as its arguments can appear
+ * in arbitrary order. Hence the name is used to make the order
+ * insignificant.
+ */
+ virtual TemplateParameterHash &templateParameterStore() = 0;
+
+ /**
+ * Same as itemSequenceCacheCells() but applies only for global
+ * variables.
+ *
+ * @see globalItemCacheCell()
+ */
+ virtual ItemSequenceCacheCell::Vector &globalItemSequenceCacheCells(const VariableSlotID slot) = 0;
+
+ /**
+ * @short Returns the previous DynamicContext. If this context is the
+ * top-level one, @c null is returned.
+ */
+ virtual DynamicContext::Ptr previousContext() const = 0;
+
+ /**
+ * @short Returns the current template mode that is in effect.
+ *
+ * If @c null is returned, it means that the default mode should be
+ * used as the current mode.
+ */
+ virtual QExplicitlySharedDataPointer<TemplateMode> currentTemplateMode() const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qfocus.cpp b/src/xmlpatterns/environment/qfocus.cpp
new file mode 100644
index 0000000..72031bf
--- /dev/null
+++ b/src/xmlpatterns/environment/qfocus.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdaytimeduration_p.h"
+
+#include "qfocus_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Focus::Focus(const DynamicContext::Ptr &prevContext) : DelegatingDynamicContext(prevContext),
+ m_contextSizeCached(-1)
+{
+ Q_ASSERT(prevContext);
+ Q_ASSERT(prevContext != this);
+}
+
+xsInteger Focus::contextPosition() const
+{
+ Q_ASSERT(m_focusIterator);
+ return m_focusIterator->position();
+}
+
+Item Focus::contextItem() const
+{
+ Q_ASSERT(m_focusIterator);
+ return m_focusIterator->current();
+}
+
+xsInteger Focus::contextSize()
+{
+ Q_ASSERT(m_focusIterator);
+ if(m_contextSizeCached == -1)
+ m_contextSizeCached = m_focusIterator->copy()->count();
+
+ Q_ASSERT_X(m_contextSizeCached == m_focusIterator->copy()->count(), Q_FUNC_INFO,
+ "If our cache is not the same as the real count, something is wrong.");
+
+ return m_contextSizeCached;
+}
+
+void Focus::setFocusIterator(const Item::Iterator::Ptr &it)
+{
+ Q_ASSERT(it);
+ m_focusIterator = it;
+}
+
+Item::Iterator::Ptr Focus::focusIterator() const
+{
+ return m_focusIterator;
+}
+
+Item Focus::currentItem() const
+{
+ /* In the case that there is no top level expression that creates a focus,
+ * fn:current() should return the focus. This logic achieves this.
+ * Effectively we traverse up our "context stack" through recursion, and
+ * start returning when we've found the top most focus. */
+
+ const Item current(m_prevContext->currentItem());
+
+ if(current.isNull())
+ return m_focusIterator->current();
+ else
+ return current;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qfocus_p.h b/src/xmlpatterns/environment/qfocus_p.h
new file mode 100644
index 0000000..94effcf
--- /dev/null
+++ b/src/xmlpatterns/environment/qfocus_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Focus_H
+#define Patternist_Focus_H
+
+#include "qdelegatingdynamiccontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A DynamicContext that maintains the focus, a sequence
+ * of items.
+ *
+ * Focus implements both the outer and inner focus. The focus is one of
+ * the things that characterizes the XPath language. The focus is what's
+ * iterated over in a predicate, whose current item can be received
+ * via the context item expression, <tt>.</tt>(the dot),
+ * and whose size is retrievable via the function <tt>fn:last()</tt>.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Focus : public DelegatingDynamicContext
+ {
+ public:
+ Focus(const DynamicContext::Ptr &prevContext);
+
+ virtual xsInteger contextPosition() const;
+ virtual Item contextItem() const;
+ virtual xsInteger contextSize();
+
+ virtual void setFocusIterator(const Item::Iterator::Ptr &it);
+ virtual Item::Iterator::Ptr focusIterator() const;
+
+ /**
+ * If there is no top level expression that sets the current item,
+ * the focus should be used. This implementation ensures that.
+ */
+ virtual Item currentItem() const;
+
+ private:
+ Item::Iterator::Ptr m_focusIterator;
+ xsInteger m_contextSizeCached;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qgenericdynamiccontext.cpp b/src/xmlpatterns/environment/qgenericdynamiccontext.cpp
new file mode 100644
index 0000000..e721052
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericdynamiccontext.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonvalues_p.h"
+#include "qfocus_p.h"
+#include "qtemplatemode_p.h"
+
+#include "qgenericdynamiccontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GenericDynamicContext::GenericDynamicContext(const NamePool::Ptr &np,
+ QAbstractMessageHandler *const errHandler,
+ const LocationHash &locations) : m_messageHandler(errHandler)
+ , m_currentDateTime(QDateTime::currentDateTime().toTimeSpec(Qt::UTC))
+ , m_outputReceiver(0)
+ , m_namePool(np)
+ , m_locations(locations)
+ , m_uriResolver(0)
+{
+ Q_ASSERT(m_messageHandler);
+ Q_ASSERT(m_namePool);
+}
+
+QExplicitlySharedDataPointer<DayTimeDuration> GenericDynamicContext::implicitTimezone() const
+{
+ /* Or what do you prefer, sir? */
+ return CommonValues::DayTimeDurationZero;
+}
+
+QAbstractMessageHandler * GenericDynamicContext::messageHandler() const
+{
+ return m_messageHandler;
+}
+
+QDateTime GenericDynamicContext::currentDateTime() const
+{
+ return m_currentDateTime;
+}
+
+xsInteger GenericDynamicContext::contextPosition() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "That this function is called makes no sense. A Focus should be used.");
+ return 0;
+}
+
+Item GenericDynamicContext::contextItem() const
+{
+ return Item();
+}
+
+xsInteger GenericDynamicContext::contextSize()
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "That this function is called makes no sense. A Focus should be used.");
+ return 0;
+}
+
+void GenericDynamicContext::setFocusIterator(const Item::Iterator::Ptr &)
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "That this function is called makes no sense. A Focus should be used.");
+}
+
+Item::Iterator::Ptr GenericDynamicContext::focusIterator() const
+{
+ return Item::Iterator::Ptr();
+}
+
+QAbstractXmlReceiver *GenericDynamicContext::outputReceiver() const
+{
+ return m_outputReceiver;
+}
+
+void GenericDynamicContext::setOutputReceiver(QAbstractXmlReceiver *const receiver)
+{
+ m_outputReceiver = receiver;
+}
+
+void GenericDynamicContext::setNodeBuilder(NodeBuilder::Ptr &builder)
+{
+ m_nodeBuilder = builder;
+}
+
+NodeBuilder::Ptr GenericDynamicContext::nodeBuilder(const QUrl &baseURI) const
+{
+ return m_nodeBuilder->create(baseURI);
+}
+
+ResourceLoader::Ptr GenericDynamicContext::resourceLoader() const
+{
+ return m_resourceLoader;
+}
+
+void GenericDynamicContext::setResourceLoader(const ResourceLoader::Ptr &loader)
+{
+ m_resourceLoader = loader;
+}
+
+ExternalVariableLoader::Ptr GenericDynamicContext::externalVariableLoader() const
+{
+ return m_externalVariableLoader;
+}
+
+void GenericDynamicContext::setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader)
+{
+ m_externalVariableLoader = loader;
+}
+
+NamePool::Ptr GenericDynamicContext::namePool() const
+{
+ return m_namePool;
+}
+
+QSourceLocation GenericDynamicContext::locationFor(const SourceLocationReflection *const reflection) const
+{
+
+ return m_locations.value(reflection->actualReflection());
+}
+
+void GenericDynamicContext::addNodeModel(const QAbstractXmlNodeModel::Ptr &nm)
+{
+ m_nodeModels.append(nm);
+}
+
+const QAbstractUriResolver *GenericDynamicContext::uriResolver() const
+{
+ return m_uriResolver;
+}
+
+ItemCacheCell &GenericDynamicContext::globalItemCacheCell(const VariableSlotID slot)
+{
+ if(slot >= m_globalItemCacheCells.size())
+ m_globalItemCacheCells.resize(qMax(slot + 1, m_globalItemCacheCells.size()));
+
+ return m_globalItemCacheCells[slot];
+}
+
+ItemSequenceCacheCell::Vector &GenericDynamicContext::globalItemSequenceCacheCells(const VariableSlotID slot)
+{
+ if(slot >= m_globalItemSequenceCacheCells.size())
+ m_globalItemSequenceCacheCells.resize(qMax(slot + 1, m_globalItemSequenceCacheCells.size()));
+
+ return m_globalItemSequenceCacheCells;
+}
+
+void GenericDynamicContext::setUriResolver(const QAbstractUriResolver *const resolver)
+{
+ m_uriResolver = resolver;
+}
+
+Item GenericDynamicContext::currentItem() const
+{
+ return Item();
+}
+
+DynamicContext::Ptr GenericDynamicContext::previousContext() const
+{
+ return DynamicContext::Ptr();
+}
+
+QExplicitlySharedDataPointer<TemplateMode> GenericDynamicContext::currentTemplateMode() const
+{
+ return QExplicitlySharedDataPointer<TemplateMode>();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qgenericdynamiccontext_p.h b/src/xmlpatterns/environment/qgenericdynamiccontext_p.h
new file mode 100644
index 0000000..1b95dfd
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericdynamiccontext_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GenericDynamicContext_H
+#define Patternist_GenericDynamicContext_H
+
+#include <QDateTime>
+#include <QVector>
+
+#include "qdaytimeduration_p.h"
+#include "qstackcontextbase_p.h"
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A DynamicContext supplying basic information that always is used.
+ *
+ * This DynamicContext is the first DynamicContext used during
+ * a run and is always used. In addition, more contexts, such as
+ * a Focus can be created.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GenericDynamicContext : public StackContextBase<DynamicContext>
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<GenericDynamicContext> Ptr;
+
+ GenericDynamicContext(const NamePool::Ptr &np,
+ QAbstractMessageHandler *const messageHandler,
+ const LocationHash &locations);
+
+ virtual xsInteger contextPosition() const;
+ /**
+ * @returns always @c null, the focus is always undefined when an GenericDynamicContext
+ * is used.
+ */
+ virtual Item contextItem() const;
+ virtual xsInteger contextSize();
+
+ virtual void setFocusIterator(const Item::Iterator::Ptr &it);
+ virtual Item::Iterator::Ptr focusIterator() const;
+
+ virtual QAbstractMessageHandler * messageHandler() const;
+ virtual QExplicitlySharedDataPointer<DayTimeDuration> implicitTimezone() const;
+ virtual QDateTime currentDateTime() const;
+
+ virtual QAbstractXmlReceiver *outputReceiver() const;
+ void setOutputReceiver(QAbstractXmlReceiver *const receiver);
+
+ virtual NodeBuilder::Ptr nodeBuilder(const QUrl &baseURI) const;
+ void setNodeBuilder(NodeBuilder::Ptr &builder);
+
+ virtual ResourceLoader::Ptr resourceLoader() const;
+ void setResourceLoader(const ResourceLoader::Ptr &loader);
+
+ virtual ExternalVariableLoader::Ptr externalVariableLoader() const;
+ void setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader);
+ virtual NamePool::Ptr namePool() const;
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const;
+ virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nm);
+ virtual const QAbstractUriResolver *uriResolver() const;
+ virtual ItemCacheCell &globalItemCacheCell(const VariableSlotID slot);
+ virtual ItemSequenceCacheCell::Vector &globalItemSequenceCacheCells(const VariableSlotID slot);
+
+ void setUriResolver(const QAbstractUriResolver *const resolver);
+
+ /**
+ * We return a null item, we have no focus.
+ */
+ virtual Item currentItem() const;
+
+ /**
+ * @short Returns always @c null, since we're always
+ * a top-level context.
+ */
+ virtual DynamicContext::Ptr previousContext() const;
+
+ virtual QExplicitlySharedDataPointer<TemplateMode> currentTemplateMode() const;
+
+ private:
+ QAbstractMessageHandler * m_messageHandler;
+ const QDateTime m_currentDateTime;
+ const DayTimeDuration::Ptr m_zoneOffset;
+ QAbstractXmlReceiver * m_outputReceiver;
+ mutable NodeBuilder::Ptr m_nodeBuilder;
+ ExternalVariableLoader::Ptr m_externalVariableLoader;
+ ResourceLoader::Ptr m_resourceLoader;
+ NamePool::Ptr m_namePool;
+ const LocationHash m_locations;
+ QAbstractXmlNodeModel::List m_nodeModels;
+ const QAbstractUriResolver * m_uriResolver;
+ ItemCacheCell::Vector m_globalItemCacheCells;
+ ItemSequenceCacheCell::Vector m_globalItemSequenceCacheCells;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qgenericstaticcontext.cpp b/src/xmlpatterns/environment/qgenericstaticcontext.cpp
new file mode 100644
index 0000000..146f468
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericstaticcontext.cpp
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* Patternist */
+#include "qbasictypesfactory_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qgenericdynamiccontext_p.h"
+#include "qfunctionfactorycollection_p.h"
+#include "qgenericnamespaceresolver_p.h"
+
+#include "qgenericstaticcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GenericStaticContext::GenericStaticContext(const NamePool::Ptr &np,
+ QAbstractMessageHandler *const handler,
+ const QUrl &aBaseURI,
+ const FunctionFactory::Ptr &factory,
+ const QXmlQuery::QueryLanguage lang) : m_boundarySpacePolicy(BSPStrip)
+ , m_constructionMode(CMPreserve)
+ , m_functionFactory(factory)
+ , m_defaultFunctionNamespace(CommonNamespaces::XFN)
+ , m_orderingEmptySequence(Greatest)
+ , m_orderingMode(Ordered)
+ , m_defaultCollation(QUrl::fromEncoded(CommonNamespaces::UNICODE_COLLATION))
+ , m_baseURI(aBaseURI)
+ , m_messageHandler(handler)
+ , m_preserveMode(Preserve)
+ , m_inheritMode(Inherit)
+ , m_namespaceResolver(lang == QXmlQuery::XQuery10
+ ? GenericNamespaceResolver::defaultXQueryBindings()
+ : GenericNamespaceResolver::defaultXSLTBindings())
+ , m_namePool(np)
+ , m_uriResolver(0)
+ , m_queryLanguage(lang)
+ , m_rangeSlot(-1)
+ , m_compatModeEnabled(false)
+{
+ /* We'll easily have at least this many AST nodes, that we need
+ * to track locations for. */
+ m_locations.reserve(30);
+
+ Q_ASSERT(np);
+ Q_ASSERT(!m_baseURI.isRelative());
+}
+
+NamespaceResolver::Ptr GenericStaticContext::namespaceBindings() const
+{
+ return m_namespaceResolver;
+}
+
+FunctionFactory::Ptr GenericStaticContext::functionSignatures() const
+{
+ return m_functionFactory;
+}
+
+DynamicContext::Ptr GenericStaticContext::dynamicContext() const
+{
+ GenericDynamicContext::Ptr context(new GenericDynamicContext(m_namePool, m_messageHandler, sourceLocations()));
+ // TODO we have many bugs here..
+ context->setResourceLoader(m_resourceLoader);
+ return context;
+}
+
+SchemaTypeFactory::Ptr GenericStaticContext::schemaDefinitions() const
+{
+ return BasicTypesFactory::self(m_namePool);
+}
+
+QUrl GenericStaticContext::baseURI() const
+{
+ Q_ASSERT_X(!m_baseURI.isRelative(), Q_FUNC_INFO,
+ "The static base-uri must be absolute. This error is most likely caused by misuing the API.");
+ return m_baseURI;
+}
+
+void GenericStaticContext::setBaseURI(const QUrl &uri)
+{
+ Q_ASSERT(!uri.isRelative());
+ m_baseURI = uri;
+}
+
+bool GenericStaticContext::compatModeEnabled() const
+{
+ return m_compatModeEnabled;
+}
+
+void GenericStaticContext::setCompatModeEnabled(const bool newVal)
+{
+ m_compatModeEnabled = newVal;
+}
+
+QUrl GenericStaticContext::defaultCollation() const
+{
+ return m_defaultCollation;
+}
+
+QAbstractMessageHandler * GenericStaticContext::messageHandler() const
+{
+ return m_messageHandler;
+}
+
+void GenericStaticContext::setDefaultCollation(const QUrl &uri)
+{
+ m_defaultCollation = uri;
+}
+
+void GenericStaticContext::setNamespaceBindings(const NamespaceResolver::Ptr &resolver)
+{
+ Q_ASSERT(resolver);
+ m_namespaceResolver = resolver;
+}
+
+StaticContext::BoundarySpacePolicy GenericStaticContext::boundarySpacePolicy() const
+{
+ return m_boundarySpacePolicy;
+}
+
+void GenericStaticContext::setBoundarySpacePolicy(const BoundarySpacePolicy policy)
+{
+ Q_ASSERT(policy == BSPPreserve || policy == BSPStrip);
+ m_boundarySpacePolicy = policy;
+}
+
+StaticContext::ConstructionMode GenericStaticContext::constructionMode() const
+{
+ return m_constructionMode;
+}
+
+void GenericStaticContext::setConstructionMode(const ConstructionMode mode)
+{
+ Q_ASSERT(mode == CMPreserve || mode == CMStrip);
+ m_constructionMode = mode;
+}
+
+StaticContext::OrderingMode GenericStaticContext::orderingMode() const
+{
+ return m_orderingMode;
+}
+
+void GenericStaticContext::setOrderingMode(const OrderingMode mode)
+{
+ Q_ASSERT(mode == Ordered || mode == Unordered);
+ m_orderingMode = mode;
+}
+
+StaticContext::OrderingEmptySequence GenericStaticContext::orderingEmptySequence() const
+{
+ return m_orderingEmptySequence;
+}
+
+void GenericStaticContext::setOrderingEmptySequence(const OrderingEmptySequence ordering)
+{
+ Q_ASSERT(ordering == Greatest || ordering == Least);
+ m_orderingEmptySequence = ordering;
+}
+
+QString GenericStaticContext::defaultFunctionNamespace() const
+{
+ return m_defaultFunctionNamespace;
+}
+
+void GenericStaticContext::setDefaultFunctionNamespace(const QString &ns)
+{
+ m_defaultFunctionNamespace = ns;
+}
+
+
+QString GenericStaticContext::defaultElementNamespace() const
+{
+ return m_defaultElementNamespace;
+}
+
+void GenericStaticContext::setDefaultElementNamespace(const QString &ns)
+{
+ m_defaultElementNamespace = ns;
+}
+
+StaticContext::InheritMode GenericStaticContext::inheritMode() const
+{
+ return m_inheritMode;
+}
+
+void GenericStaticContext::setInheritMode(const InheritMode mode)
+{
+ Q_ASSERT(mode == Inherit || mode == NoInherit);
+ m_inheritMode = mode;
+}
+
+StaticContext::PreserveMode GenericStaticContext::preserveMode() const
+{
+ return m_preserveMode;
+}
+
+void GenericStaticContext::setPreserveMode(const PreserveMode mode)
+{
+ Q_ASSERT(mode == Preserve || mode == NoPreserve);
+ m_preserveMode = mode;
+}
+
+ItemType::Ptr GenericStaticContext::contextItemType() const
+{
+ return m_contextItemType;
+}
+
+ItemType::Ptr GenericStaticContext::currentItemType() const
+{
+ return contextItemType();
+}
+
+void GenericStaticContext::setContextItemType(const ItemType::Ptr &type)
+{
+ m_contextItemType = type;
+}
+
+StaticContext::Ptr GenericStaticContext::copy() const
+{
+ GenericStaticContext *const retval = new GenericStaticContext(m_namePool, m_messageHandler, m_baseURI, m_functionFactory, m_queryLanguage);
+ const NamespaceResolver::Ptr newSolver(new GenericNamespaceResolver(m_namespaceResolver->bindings()));
+
+ retval->setNamespaceBindings(newSolver);
+ retval->setDefaultCollation(m_defaultCollation);
+ retval->setBoundarySpacePolicy(m_boundarySpacePolicy);
+ retval->setConstructionMode(m_constructionMode);
+ retval->setOrderingMode(m_orderingMode);
+ retval->setOrderingEmptySequence(m_orderingEmptySequence);
+ retval->setDefaultFunctionNamespace(m_defaultFunctionNamespace);
+ retval->setInheritMode(m_inheritMode);
+ retval->setPreserveMode(m_preserveMode);
+ retval->setExternalVariableLoader(m_externalVariableLoader);
+ retval->setResourceLoader(m_resourceLoader);
+ retval->setContextItemType(m_contextItemType);
+ retval->m_locations = m_locations;
+
+ return StaticContext::Ptr(retval);
+}
+
+ResourceLoader::Ptr GenericStaticContext::resourceLoader() const
+{
+ return m_resourceLoader;
+}
+
+void GenericStaticContext::setResourceLoader(const ResourceLoader::Ptr &loader)
+{
+ m_resourceLoader = loader;
+}
+
+ExternalVariableLoader::Ptr GenericStaticContext::externalVariableLoader() const
+{
+ return m_externalVariableLoader;
+}
+
+void GenericStaticContext::setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader)
+{
+ m_externalVariableLoader = loader;
+}
+
+NamePool::Ptr GenericStaticContext::namePool() const
+{
+ return m_namePool;
+}
+
+void GenericStaticContext::addLocation(const SourceLocationReflection *const reflection,
+ const QSourceLocation &location)
+{
+ Q_ASSERT(!location.isNull());
+ Q_ASSERT_X(reflection, Q_FUNC_INFO,
+ "The reflection cannot be zero.");
+ m_locations.insert(reflection, location);
+}
+
+StaticContext::LocationHash GenericStaticContext::sourceLocations() const
+{
+ return m_locations;
+}
+
+QSourceLocation GenericStaticContext::locationFor(const SourceLocationReflection *const reflection) const
+{
+ return m_locations.value(reflection->actualReflection());
+}
+
+QAbstractUriResolver *GenericStaticContext::uriResolver() const
+{
+ return m_uriResolver;
+}
+
+VariableSlotID GenericStaticContext::currentRangeSlot() const
+{
+ return m_rangeSlot;
+}
+
+VariableSlotID GenericStaticContext::allocateRangeSlot()
+{
+ ++m_rangeSlot;
+ return m_rangeSlot;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qgenericstaticcontext_p.h b/src/xmlpatterns/environment/qgenericstaticcontext_p.h
new file mode 100644
index 0000000..1ee9949
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericstaticcontext_p.h
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GenericStaticContext_H
+#define Patternist_GenericStaticContext_H
+
+#include <QUrl>
+#include <QXmlQuery>
+
+#include "qstaticcontext_p.h"
+#include "qfunctionfactory_p.h"
+#include "qschematypefactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides setters and getters for the properties defined in StaticContext.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GenericStaticContext : public StaticContext
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<GenericStaticContext> Ptr;
+ /**
+ * Constructs a GenericStaticContext. The components are initialized as per
+ * the recommended default values in XQuery 1.0. <tt>Default order for empty sequences</tt>,
+ * orderingEmptySequence(), is initialized to Greatest.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-xq-static-context-components">XQuery
+ * 1.0: An XML Query Language, C.1 Static Context Components</a>
+ * @param errorHandler the error handler. May be null.
+ * @param np the NamePool. May not be null.
+ * @param aBaseURI the base URI in the static context. Must be absolute
+ * and valid.
+ */
+ GenericStaticContext(const NamePool::Ptr &np,
+ QAbstractMessageHandler *const errorHandler,
+ const QUrl &aBaseURI,
+ const FunctionFactory::Ptr &factory,
+ const QXmlQuery::QueryLanguage lang);
+
+ virtual NamespaceResolver::Ptr namespaceBindings() const;
+ virtual void setNamespaceBindings(const NamespaceResolver::Ptr &);
+
+ virtual FunctionFactory::Ptr functionSignatures() const;
+ virtual SchemaTypeFactory::Ptr schemaDefinitions() const;
+
+ /**
+ * Returns a DynamicContext used for evaluation at compile time.
+ *
+ * @bug The DynamicContext isn't stable. It should be cached privately.
+ */
+ virtual DynamicContext::Ptr dynamicContext() const;
+
+ virtual QUrl baseURI() const;
+ virtual void setBaseURI(const QUrl &uri);
+
+ virtual bool compatModeEnabled() const;
+ virtual void setCompatModeEnabled(const bool newVal);
+
+ /**
+ * @returns always the Unicode codepoint collation URI
+ */
+ virtual QUrl defaultCollation() const;
+
+ virtual QAbstractMessageHandler * messageHandler() const;
+
+ virtual void setDefaultCollation(const QUrl &uri);
+
+ virtual BoundarySpacePolicy boundarySpacePolicy() const;
+ virtual void setBoundarySpacePolicy(const BoundarySpacePolicy policy);
+
+ virtual ConstructionMode constructionMode() const;
+ virtual void setConstructionMode(const ConstructionMode mode);
+
+ virtual OrderingMode orderingMode() const;
+ virtual void setOrderingMode(const OrderingMode mode);
+ virtual OrderingEmptySequence orderingEmptySequence() const;
+ virtual void setOrderingEmptySequence(const OrderingEmptySequence ordering);
+
+ virtual QString defaultFunctionNamespace() const;
+ virtual void setDefaultFunctionNamespace(const QString &ns);
+
+ virtual QString defaultElementNamespace() const;
+ virtual void setDefaultElementNamespace(const QString &ns);
+
+ virtual InheritMode inheritMode() const;
+ virtual void setInheritMode(const InheritMode mode);
+
+ virtual PreserveMode preserveMode() const;
+ virtual void setPreserveMode(const PreserveMode mode);
+
+ virtual ItemType::Ptr contextItemType() const;
+ void setContextItemType(const ItemType::Ptr &type);
+ virtual ItemType::Ptr currentItemType() const;
+
+ virtual StaticContext::Ptr copy() const;
+
+ virtual ResourceLoader::Ptr resourceLoader() const;
+ void setResourceLoader(const ResourceLoader::Ptr &loader);
+
+ virtual ExternalVariableLoader::Ptr externalVariableLoader() const;
+ void setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader);
+ virtual NamePool::Ptr namePool() const;
+
+ virtual void addLocation(const SourceLocationReflection *const reflection,
+ const QSourceLocation &location);
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const;
+
+ virtual LocationHash sourceLocations() const;
+ virtual QAbstractUriResolver *uriResolver() const;
+
+ virtual VariableSlotID currentRangeSlot() const;
+ virtual VariableSlotID allocateRangeSlot();
+
+ private:
+ BoundarySpacePolicy m_boundarySpacePolicy;
+ ConstructionMode m_constructionMode;
+ FunctionFactory::Ptr m_functionFactory;
+ QString m_defaultElementNamespace;
+ QString m_defaultFunctionNamespace;
+ OrderingEmptySequence m_orderingEmptySequence;
+ OrderingMode m_orderingMode;
+ QUrl m_defaultCollation;
+ QUrl m_baseURI;
+ QAbstractMessageHandler * m_messageHandler;
+ PreserveMode m_preserveMode;
+ InheritMode m_inheritMode;
+ NamespaceResolver::Ptr m_namespaceResolver;
+ ExternalVariableLoader::Ptr m_externalVariableLoader;
+ ResourceLoader::Ptr m_resourceLoader;
+ const NamePool::Ptr m_namePool;
+ ItemType::Ptr m_contextItemType;
+ LocationHash m_locations;
+ QAbstractUriResolver * m_uriResolver;
+ QXmlQuery::QueryLanguage m_queryLanguage;
+ VariableSlotID m_rangeSlot;
+ bool m_compatModeEnabled;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qreceiverdynamiccontext.cpp b/src/xmlpatterns/environment/qreceiverdynamiccontext.cpp
new file mode 100644
index 0000000..8425fea
--- /dev/null
+++ b/src/xmlpatterns/environment/qreceiverdynamiccontext.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qreceiverdynamiccontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ReceiverDynamicContext::
+ReceiverDynamicContext(const DynamicContext::Ptr &prevContext,
+ QAbstractXmlReceiver *const receiver) : DelegatingDynamicContext(prevContext)
+ , m_receiver(receiver)
+{
+ Q_ASSERT(receiver);
+}
+
+QAbstractXmlReceiver *ReceiverDynamicContext::outputReceiver() const
+{
+ return m_receiver;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qreceiverdynamiccontext_p.h b/src/xmlpatterns/environment/qreceiverdynamiccontext_p.h
new file mode 100644
index 0000000..ab3359b
--- /dev/null
+++ b/src/xmlpatterns/environment/qreceiverdynamiccontext_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ReceiverDynamicContext_H
+#define Patternist_ReceiverDynamicContext_H
+
+#include "qdelegatingdynamiccontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A DynamicContext that has a specialized QAbstractXmlReceiver.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ReceiverDynamicContext : public DelegatingDynamicContext
+ {
+ public:
+ /**
+ * Construct a ReceiverDynamicContext and passes @p prevContext to its super class. This
+ * constructor is typically used when the super class is DelegatingDynamicContext.
+ */
+ ReceiverDynamicContext(const DynamicContext::Ptr &prevContext,
+ QAbstractXmlReceiver *const receiver);
+
+ virtual QAbstractXmlReceiver *outputReceiver() const;
+
+ private:
+ QAbstractXmlReceiver *const m_receiver;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qreportcontext.cpp b/src/xmlpatterns/environment/qreportcontext.cpp
new file mode 100644
index 0000000..c82acba
--- /dev/null
+++ b/src/xmlpatterns/environment/qreportcontext.cpp
@@ -0,0 +1,479 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qabstractmessagehandler.h"
+
+#include "qcommonnamespaces_p.h"
+#include "qexpression_p.h"
+
+#include "qreportcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ReportContext::~ReportContext()
+{
+}
+
+QString ReportContext::finalizeDescription(const QString &desc)
+{
+ return QLatin1String("<html xmlns='http://www.w3.org/1999/xhtml/'><body><p>")
+ + desc
+ + QLatin1String("</p></body></html>");
+}
+
+void ReportContext::warning(const QString &description,
+ const QSourceLocation &sourceLocation)
+{
+ messageHandler()->message(QtWarningMsg, finalizeDescription(description), QUrl(), sourceLocation);
+}
+
+void ReportContext::createError(const QString &description,
+ const QtMsgType type,
+ const QUrl &id,
+ const QSourceLocation &sourceLocation) const
+{
+ messageHandler()->message(type, finalizeDescription(description), id, sourceLocation);
+ throw Exception(true);
+}
+
+void ReportContext::error(const QString &msg,
+ const ErrorCode code,
+ const QSourceLocation &sourceLocation)
+{
+ createError(msg, QtFatalMsg,
+ QUrl(CommonNamespaces::XPERR + QLatin1Char('#') + codeToString(code)),
+ sourceLocation);
+}
+
+QSourceLocation ReportContext::lookupSourceLocation(const SourceLocationReflection *const r) const
+{
+ Q_ASSERT(r);
+ const SourceLocationReflection *const actual = r->actualReflection();
+ Q_ASSERT(actual);
+
+ const QSourceLocation &sl = actual->sourceLocation();
+
+ if(sl.isNull())
+ {
+ Q_ASSERT_X(!locationFor(actual).isNull(), Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("No location is available for: %1").arg(actual->description())));
+ return locationFor(actual);
+ }
+ else
+ return sl;
+}
+
+void ReportContext::error(const QString &message,
+ const ReportContext::ErrorCode errorCode,
+ const SourceLocationReflection *const reflection)
+{
+ Q_ASSERT(reflection);
+ error(message, errorCode, lookupSourceLocation(reflection));
+}
+
+void ReportContext::error(const QString &msg,
+ const QXmlName qname,
+ const SourceLocationReflection *const reflection)
+{
+ Q_ASSERT(!qname.isNull());
+ createError(msg, QtFatalMsg,
+ QUrl(namePool()->stringForNamespace(qname.namespaceURI()) + QLatin1Char('#') + namePool()->stringForLocalName(qname.localName())),
+ lookupSourceLocation(reflection));
+}
+
+QString ReportContext::codeFromURI(const QString &typeURI,
+ QString &uri)
+{
+ /* Wouldn't surprise me if this can be done more efficiently. */
+ QUrl source(typeURI);
+
+ const QString code(source.fragment());
+ source.setFragment(QString());
+ uri = source.toString();
+ return code;
+}
+
+QString ReportContext::codeToString(const ReportContext::ErrorCode code)
+{
+ const char *result = 0;
+
+ switch(code)
+ {
+ /* Alphabetically. */
+ case FOAR0001: result = "FOAR0001"; break;
+ case FOAR0002: result = "FOAR0002"; break;
+ case FOCA0001: result = "FOCA0001"; break;
+ case FOCA0002: result = "FOCA0002"; break;
+ case FOCA0003: result = "FOCA0003"; break;
+ case FOCA0005: result = "FOCA0005"; break;
+ case FOCA0006: result = "FOCA0006"; break;
+ case FOCH0001: result = "FOCH0001"; break;
+ case FOCH0002: result = "FOCH0002"; break;
+ case FOCH0003: result = "FOCH0003"; break;
+ case FOCH0004: result = "FOCH0004"; break;
+ case FODC0001: result = "FODC0001"; break;
+ case FODC0002: result = "FODC0002"; break;
+ case FODC0003: result = "FODC0003"; break;
+ case FODC0004: result = "FODC0004"; break;
+ case FODC0005: result = "FODC0005"; break;
+ case FODT0001: result = "FODT0001"; break;
+ case FODT0002: result = "FODT0002"; break;
+ case FODT0003: result = "FODT0003"; break;
+ case FOER0000: result = "FOER0000"; break;
+ case FONS0004: result = "FONS0004"; break;
+ case FONS0005: result = "FONS0005"; break;
+ case FORG0001: result = "FORG0001"; break;
+ case FORG0002: result = "FORG0002"; break;
+ case FORG0003: result = "FORG0003"; break;
+ case FORG0004: result = "FORG0004"; break;
+ case FORG0005: result = "FORG0005"; break;
+ case FORG0006: result = "FORG0006"; break;
+ case FORG0008: result = "FORG0008"; break;
+ case FORG0009: result = "FORG0009"; break;
+ case FORX0001: result = "FORX0001"; break;
+ case FORX0002: result = "FORX0002"; break;
+ case FORX0003: result = "FORX0003"; break;
+ case FORX0004: result = "FORX0004"; break;
+ case FOTY0012: result = "FOTY0012"; break;
+ case SENR0001: result = "SENR0001"; break;
+ case SEPM0004: result = "SEPM0004"; break;
+ case SEPM0009: result = "SEPM0009"; break;
+ case SEPM0010: result = "SEPM0010"; break;
+ case SEPM0016: result = "SEPM0016"; break;
+ case SERE0003: result = "SERE0003"; break;
+ case SERE0005: result = "SERE0005"; break;
+ case SERE0006: result = "SERE0006"; break;
+ case SERE0008: result = "SERE0008"; break;
+ case SERE0012: result = "SERE0012"; break;
+ case SERE0014: result = "SERE0014"; break;
+ case SERE0015: result = "SERE0015"; break;
+ case SESU0007: result = "SESU0007"; break;
+ case SESU0011: result = "SESU0011"; break;
+ case SESU0013: result = "SESU0013"; break;
+ case XPDY0002: result = "XPDY0002"; break;
+ case XPDY0021: result = "XPDY0021"; break;
+ case XPDY0050: result = "XPDY0050"; break;
+ case XPST0001: result = "XPST0001"; break;
+ case XPST0003: result = "XPST0003"; break;
+ case XPST0005: result = "XPST0005"; break;
+ case XPST0008: result = "XPST0008"; break;
+ case XPST0010: result = "XPST0010"; break;
+ case XPST0017: result = "XPST0017"; break;
+ case XPST0051: result = "XPST0051"; break;
+ case XPST0080: result = "XPST0080"; break;
+ case XPST0081: result = "XPST0081"; break;
+ case XPST0083: result = "XPST0083"; break;
+ case XPTY0004: result = "XPTY0004"; break;
+ case XPTY0006: result = "XPTY0006"; break;
+ case XPTY0007: result = "XPTY0007"; break;
+ case XPTY0018: result = "XPTY0018"; break;
+ case XPTY0019: result = "XPTY0019"; break;
+ case XPTY0020: result = "XPTY0020"; break;
+ case XQDY0025: result = "XQDY0025"; break;
+ case XQDY0026: result = "XQDY0026"; break;
+ case XQDY0027: result = "XQDY0027"; break;
+ case XQDY0029: result = "XQDY0029"; break;
+ case XQDY0041: result = "XQDY0041"; break;
+ case XQDY0044: result = "XQDY0044"; break;
+ case XQDY0052: result = "XQDY0052"; break;
+ case XQDY0061: result = "XQDY0061"; break;
+ case XQDY0062: result = "XQDY0062"; break;
+ case XQDY0064: result = "XQDY0064"; break;
+ case XQDY0072: result = "XQDY0072"; break;
+ case XQDY0074: result = "XQDY0074"; break;
+ case XQDY0084: result = "XQDY0084"; break;
+ case XQDY0091: result = "XQDY0091"; break;
+ case XQDY0092: result = "XQDY0092"; break;
+ case XQST0009: result = "XQST0009"; break;
+ case XQST0012: result = "XQST0012"; break;
+ case XQST0013: result = "XQST0013"; break;
+ case XQST0014: result = "XQST0014"; break;
+ case XQST0015: result = "XQST0015"; break;
+ case XQST0016: result = "XQST0016"; break;
+ case XQST0022: result = "XQST0022"; break;
+ case XQST0031: result = "XQST0031"; break;
+ case XQST0032: result = "XQST0032"; break;
+ case XQST0033: result = "XQST0033"; break;
+ case XQST0034: result = "XQST0034"; break;
+ case XQST0035: result = "XQST0035"; break;
+ case XQST0036: result = "XQST0036"; break;
+ case XQST0037: result = "XQST0037"; break;
+ case XQST0038: result = "XQST0038"; break;
+ case XQST0039: result = "XQST0039"; break;
+ case XQST0040: result = "XQST0040"; break;
+ case XQST0042: result = "XQST0042"; break;
+ case XQST0043: result = "XQST0043"; break;
+ case XQST0045: result = "XQST0045"; break;
+ case XQST0046: result = "XQST0046"; break;
+ case XQST0047: result = "XQST0047"; break;
+ case XQST0048: result = "XQST0048"; break;
+ case XQST0049: result = "XQST0049"; break;
+ case XQST0053: result = "XQST0053"; break;
+ case XQST0054: result = "XQST0054"; break;
+ case XQST0055: result = "XQST0055"; break;
+ case XQST0056: result = "XQST0056"; break;
+ case XQST0057: result = "XQST0057"; break;
+ case XQST0058: result = "XQST0058"; break;
+ case XQST0059: result = "XQST0059"; break;
+ case XQST0060: result = "XQST0060"; break;
+ case XQST0063: result = "XQST0063"; break;
+ case XQST0065: result = "XQST0065"; break;
+ case XQST0066: result = "XQST0066"; break;
+ case XQST0067: result = "XQST0067"; break;
+ case XQST0068: result = "XQST0068"; break;
+ case XQST0069: result = "XQST0069"; break;
+ case XQST0070: result = "XQST0070"; break;
+ case XQST0071: result = "XQST0071"; break;
+ case XQST0073: result = "XQST0073"; break;
+ case XQST0075: result = "XQST0075"; break;
+ case XQST0076: result = "XQST0076"; break;
+ case XQST0077: result = "XQST0077"; break;
+ case XQST0078: result = "XQST0078"; break;
+ case XQST0079: result = "XQST0079"; break;
+ case XQST0082: result = "XQST0082"; break;
+ case XQST0085: result = "XQST0085"; break;
+ case XQST0087: result = "XQST0087"; break;
+ case XQST0088: result = "XQST0088"; break;
+ case XQST0089: result = "XQST0089"; break;
+ case XQST0090: result = "XQST0090"; break;
+ case XQST0093: result = "XQST0093"; break;
+ case XQTY0023: result = "XQTY0023"; break;
+ case XQTY0024: result = "XQTY0024"; break;
+ case XQTY0028: result = "XQTY0028"; break;
+ case XQTY0030: result = "XQTY0030"; break;
+ case XQTY0086: result = "XQTY0086"; break;
+ case XTDE0030: result = "XTDE0030"; break;
+ case XTDE0040: result = "XTDE0040"; break;
+ case XTDE0045: result = "XTDE0045"; break;
+ case XTDE0047: result = "XTDE0047"; break;
+ case XTDE0050: result = "XTDE0050"; break;
+ case XTDE0060: result = "XTDE0060"; break;
+ case XTDE0160: result = "XTDE0160"; break;
+ case XTDE0290: result = "XTDE0290"; break;
+ case XTDE0410: result = "XTDE0410"; break;
+ case XTDE0420: result = "XTDE0420"; break;
+ case XTDE0430: result = "XTDE0430"; break;
+ case XTDE0440: result = "XTDE0440"; break;
+ case XTDE0485: result = "XTDE0485"; break;
+ case XTDE0560: result = "XTDE0560"; break;
+ case XTDE0610: result = "XTDE0610"; break;
+ case XTDE0640: result = "XTDE0640"; break;
+ case XTDE0700: result = "XTDE0700"; break;
+ case XTDE0820: result = "XTDE0820"; break;
+ case XTDE0830: result = "XTDE0830"; break;
+ case XTDE0835: result = "XTDE0835"; break;
+ case XTDE0850: result = "XTDE0850"; break;
+ case XTDE0855: result = "XTDE0855"; break;
+ case XTDE0860: result = "XTDE0860"; break;
+ case XTDE0865: result = "XTDE0865"; break;
+ case XTDE0890: result = "XTDE0890"; break;
+ case XTDE0905: result = "XTDE0905"; break;
+ case XTDE0920: result = "XTDE0920"; break;
+ case XTDE0925: result = "XTDE0925"; break;
+ case XTDE0930: result = "XTDE0930"; break;
+ case XTDE0980: result = "XTDE0980"; break;
+ case XTDE1030: result = "XTDE1030"; break;
+ case XTDE1035: result = "XTDE1035"; break;
+ case XTDE1110: result = "XTDE1110"; break;
+ case XTDE1140: result = "XTDE1140"; break;
+ case XTDE1145: result = "XTDE1145"; break;
+ case XTDE1150: result = "XTDE1150"; break;
+ case XTDE1170: result = "XTDE1170"; break;
+ case XTDE1190: result = "XTDE1190"; break;
+ case XTDE1200: result = "XTDE1200"; break;
+ case XTDE1260: result = "XTDE1260"; break;
+ case XTDE1270: result = "XTDE1270"; break;
+ case XTDE1280: result = "XTDE1280"; break;
+ case XTDE1310: result = "XTDE1310"; break;
+ case XTDE1340: result = "XTDE1340"; break;
+ case XTDE1350: result = "XTDE1350"; break;
+ case XTDE1360: result = "XTDE1360"; break;
+ case XTDE1370: result = "XTDE1370"; break;
+ case XTDE1380: result = "XTDE1380"; break;
+ case XTDE1390: result = "XTDE1390"; break;
+ case XTDE1400: result = "XTDE1400"; break;
+ case XTDE1420: result = "XTDE1420"; break;
+ case XTDE1425: result = "XTDE1425"; break;
+ case XTDE1428: result = "XTDE1428"; break;
+ case XTDE1440: result = "XTDE1440"; break;
+ case XTDE1450: result = "XTDE1450"; break;
+ case XTDE1460: result = "XTDE1460"; break;
+ case XTDE1480: result = "XTDE1480"; break;
+ case XTDE1490: result = "XTDE1490"; break;
+ case XTDE1665: result = "XTDE1665"; break;
+ case XTMM9000: result = "XTMM9000"; break;
+ case XTRE0270: result = "XTRE0270"; break;
+ case XTRE0540: result = "XTRE0540"; break;
+ case XTRE0795: result = "XTRE0795"; break;
+ case XTRE1160: result = "XTRE1160"; break;
+ case XTRE1495: result = "XTRE1495"; break;
+ case XTRE1500: result = "XTRE1500"; break;
+ case XTRE1620: result = "XTRE1620"; break;
+ case XTRE1630: result = "XTRE1630"; break;
+ case XTSE0010: result = "XTSE0010"; break;
+ case XTSE0020: result = "XTSE0020"; break;
+ case XTSE0080: result = "XTSE0080"; break;
+ case XTSE0090: result = "XTSE0090"; break;
+ case XTSE0110: result = "XTSE0110"; break;
+ case XTSE0120: result = "XTSE0120"; break;
+ case XTSE0125: result = "XTSE0125"; break;
+ case XTSE0130: result = "XTSE0130"; break;
+ case XTSE0150: result = "XTSE0150"; break;
+ case XTSE0165: result = "XTSE0165"; break;
+ case XTSE0170: result = "XTSE0170"; break;
+ case XTSE0180: result = "XTSE0180"; break;
+ case XTSE0190: result = "XTSE0190"; break;
+ case XTSE0200: result = "XTSE0200"; break;
+ case XTSE0210: result = "XTSE0210"; break;
+ case XTSE0215: result = "XTSE0215"; break;
+ case XTSE0220: result = "XTSE0220"; break;
+ case XTSE0260: result = "XTSE0260"; break;
+ case XTSE0265: result = "XTSE0265"; break;
+ case XTSE0280: result = "XTSE0280"; break;
+ case XTSE0340: result = "XTSE0340"; break;
+ case XTSE0350: result = "XTSE0350"; break;
+ case XTSE0370: result = "XTSE0370"; break;
+ case XTSE0500: result = "XTSE0500"; break;
+ case XTSE0530: result = "XTSE0530"; break;
+ case XTSE0550: result = "XTSE0550"; break;
+ case XTSE0580: result = "XTSE0580"; break;
+ case XTSE0620: result = "XTSE0620"; break;
+ case XTSE0630: result = "XTSE0630"; break;
+ case XTSE0650: result = "XTSE0650"; break;
+ case XTSE0660: result = "XTSE0660"; break;
+ case XTSE0670: result = "XTSE0670"; break;
+ case XTSE0680: result = "XTSE0680"; break;
+ case XTSE0690: result = "XTSE0690"; break;
+ case XTSE0710: result = "XTSE0710"; break;
+ case XTSE0720: result = "XTSE0720"; break;
+ case XTSE0740: result = "XTSE0740"; break;
+ case XTSE0760: result = "XTSE0760"; break;
+ case XTSE0770: result = "XTSE0770"; break;
+ case XTSE0805: result = "XTSE0805"; break;
+ case XTSE0808: result = "XTSE0808"; break;
+ case XTSE0809: result = "XTSE0809"; break;
+ case XTSE0810: result = "XTSE0810"; break;
+ case XTSE0812: result = "XTSE0812"; break;
+ case XTSE0840: result = "XTSE0840"; break;
+ case XTSE0870: result = "XTSE0870"; break;
+ case XTSE0880: result = "XTSE0880"; break;
+ case XTSE0910: result = "XTSE0910"; break;
+ case XTSE0940: result = "XTSE0940"; break;
+ case XTSE0975: result = "XTSE0975"; break;
+ case XTSE1015: result = "XTSE1015"; break;
+ case XTSE1017: result = "XTSE1017"; break;
+ case XTSE1040: result = "XTSE1040"; break;
+ case XTSE1060: result = "XTSE1060"; break;
+ case XTSE1070: result = "XTSE1070"; break;
+ case XTSE1080: result = "XTSE1080"; break;
+ case XTSE1090: result = "XTSE1090"; break;
+ case XTSE1130: result = "XTSE1130"; break;
+ case XTSE1205: result = "XTSE1205"; break;
+ case XTSE1210: result = "XTSE1210"; break;
+ case XTSE1220: result = "XTSE1220"; break;
+ case XTSE1290: result = "XTSE1290"; break;
+ case XTSE1295: result = "XTSE1295"; break;
+ case XTSE1300: result = "XTSE1300"; break;
+ case XTSE1430: result = "XTSE1430"; break;
+ case XTSE1505: result = "XTSE1505"; break;
+ case XTSE1520: result = "XTSE1520"; break;
+ case XTSE1530: result = "XTSE1530"; break;
+ case XTSE1560: result = "XTSE1560"; break;
+ case XTSE1570: result = "XTSE1570"; break;
+ case XTSE1580: result = "XTSE1580"; break;
+ case XTSE1590: result = "XTSE1590"; break;
+ case XTSE1600: result = "XTSE1600"; break;
+ case XTSE1650: result = "XTSE1650"; break;
+ case XTSE1660: result = "XTSE1660"; break;
+ case XTTE0505: result = "XTTE0505"; break;
+ case XTTE0510: result = "XTTE0510"; break;
+ case XTTE0520: result = "XTTE0520"; break;
+ case XTTE0570: result = "XTTE0570"; break;
+ case XTTE0590: result = "XTTE0590"; break;
+ case XTTE0600: result = "XTTE0600"; break;
+ case XTTE0780: result = "XTTE0780"; break;
+ case XTTE0790: result = "XTTE0790"; break;
+ case XTTE0950: result = "XTTE0950"; break;
+ case XTTE0990: result = "XTTE0990"; break;
+ case XTTE1000: result = "XTTE1000"; break;
+ case XTTE1020: result = "XTTE1020"; break;
+ case XTTE1100: result = "XTTE1100"; break;
+ case XTTE1120: result = "XTTE1120"; break;
+ case XTTE1510: result = "XTTE1510"; break;
+ case XTTE1512: result = "XTTE1512"; break;
+ case XTTE1515: result = "XTTE1515"; break;
+ case XTTE1540: result = "XTTE1540"; break;
+ case XTTE1545: result = "XTTE1545"; break;
+ case XTTE1550: result = "XTTE1550"; break;
+ case XTTE1555: result = "XTTE1555"; break;
+ case XSDError: result = "XSDError"; break;
+ }
+
+ Q_ASSERT_X(result, Q_FUNC_INFO, "Unknown enum value.");
+ return QLatin1String(result);
+}
+
+QUrl ReportContext::resolveURI(const QUrl &relative,
+ const QUrl &baseURI) const
+{
+ Q_ASSERT_X(!baseURI.isRelative(), Q_FUNC_INFO,
+ "The base URI passed from the engine wasn't absolute.");
+
+ const QAbstractUriResolver *const resolver(uriResolver());
+
+ if(resolver)
+ {
+ const QUrl final(resolver->resolve(relative, baseURI));
+ Q_ASSERT_X(final.isValid() || final.isEmpty(), Q_FUNC_INFO,
+ "The QAbstractUriResolver must return a valid URI.");
+ Q_ASSERT_X(!final.isRelative(), Q_FUNC_INFO,
+ "The QAbstractUriResolver must return an absolute URI.");
+ return final;
+ }
+ else
+ return baseURI.resolved(relative);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qreportcontext_p.h b/src/xmlpatterns/environment/qreportcontext_p.h
new file mode 100644
index 0000000..067c1d3
--- /dev/null
+++ b/src/xmlpatterns/environment/qreportcontext_p.h
@@ -0,0 +1,2464 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ReportContext_H
+#define Patternist_ReportContext_H
+
+#include <QSharedData>
+#include <QAbstractUriResolver>
+#include <QSourceLocation>
+
+#include "qnamepool_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractMessageHandler;
+class QSourceLocation;
+class QString;
+
+namespace QPatternist
+{
+ class SourceLocationReflection;
+
+ /**
+ * @short A callback for reporting errors.
+ *
+ * ReportContext receives messages of various severity and type via its
+ * functions warning() and error(). In turn, ReportContext create Message instances
+ * and submit them to the QAbstractMessageHandler instance returned by messageHandler().
+ *
+ * The Message attributes are set as follows:
+ *
+ * - Message::description() - A translated, human-readable description
+ * - Message::type() - Message::Error if a static, dynamic or type error was encountered
+ * that halted compilation or evaluation, or Message::Warning in case of a warning
+ * - Message::identifier() - This is a URI consisting of the error namespace with the
+ * error code as fragment. For example, a Message representing a syntax error
+ * would return the type "http://www.w3.org/2005/xqt-errors#XPST0003". The convenience
+ * function codeFromURI() can be used to extract the error code. The error namespace
+ * is typically the namespace for XPath and XQuery errors(as in the previous example), but
+ * can also be user defined.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-identifying-errors">XML Path Language
+ * (XPath) 2.0, 2.3.2 Identifying and Reporting Errors</a>
+ * @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 <frans.englich@nokia.com>
+ * @warning This file is auto-generated from extractErrorCodes.xsl. Any
+ * modifications done to this file are lost.
+ */
+ class Q_AUTOTEST_EXPORT ReportContext : public QSharedData
+ {
+ public:
+ typedef QHash<const SourceLocationReflection *, QSourceLocation> LocationHash;
+
+ /**
+ * A smart pointer wrapping ReportContext instances.
+ */
+ typedef QExplicitlySharedDataPointer<ReportContext> Ptr;
+
+ /**
+ * @short Default constructors.
+ *
+ * For some reason GCC fails to synthesize it, so we provide an empty
+ * one here.
+ */
+ inline ReportContext() {}
+
+ virtual ~ReportContext();
+
+ /**
+ * Error codes that corresponds to the error codes defined in the
+ * relevant specifications. They are used throughout the API for
+ * identifying error conditions.
+ *
+ * While strings could have been used for identifying errors, enums
+ * reduces bugs by providing type safety.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#errors">XML
+ * Path Language (XPath) 2.0, 2.3 Error Handling</a>
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#d1e10985">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, C Error Summary</a>
+ * @see <a href="http://www.w3.org/TR/xslt20/#error-summary">XSL Transformations
+ * (XSLT) Version 2.0, E Summary of Error Conditions (Non-Normative)</a>
+ * @note The enumerator values' Doxygen documentation is copied from the
+ * W3C documents
+ * <a href="http://www.w3.org/TR/xpath-functions">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators</a>,
+ * <a href="http://www.w3.org/TR/xpath20">XML Path Language (XPath) 2.0</a>, and
+ * <a href="http://www.w3.org/TR/xslt20/">XSL Transformations (XSLT)
+ * Version 2.0</a>, respectively. The doxygen documentation is therefore covered
+ * by the following legal notice:
+ * "Copyright @ 2005 W3C&reg; (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
+ * <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and
+ * <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document
+ * use</a> rules apply."
+ * @warning This enumerator is auto-generated from the relevant specifications
+ * by the XSL-T stylesheet extractErrorCodes.xsl. Hence, any modifications
+ * done to this file, in contrary to the stylesheet, are therefore lost.
+ */
+ enum ErrorCode
+ {
+ /**
+ * XML Schema error code.
+ */
+ XSDError,
+
+ /**
+ * It is a static error if analysis of an expression relies on some
+ * component of the static context that has not been assigned a
+ * value.
+ */
+ XPST0001,
+
+ /**
+ * It is a dynamic error if evaluation of an expression relies on
+ * some part of the dynamic context that has not been assigned a
+ * value.
+ */
+ XPDY0002,
+
+ /**
+ * It is a static error if an expression is not a valid instance
+ * of the grammar defined in A.1 EBNF.
+ */
+ XPST0003,
+
+ /**
+ * It is a type error if, during the static analysis phase, an expression
+ * is found to have a static type that is not appropriate for the
+ * context in which the expression occurs, or during the dynamic
+ * evaluation phase, the dynamic type of a value does not match
+ * a required type as specified by the matching rules in 2.5.4 SequenceType
+ * Matching.
+ */
+ XPTY0004,
+
+ /**
+ * During the analysis phase, it is a static error if the static
+ * type assigned to an expression other than the expression () or
+ * data(()) is empty-sequence().
+ */
+ XPST0005,
+
+ /**
+ * (Not currently used.)
+ */
+ XPTY0006,
+
+ /**
+ * (Not currently used.)
+ */
+ XPTY0007,
+
+ /**
+ * It is a static error if an expression refers to an element name,
+ * attribute name, schema type name, namespace prefix, or variable
+ * name that is not defined in the static context, except for an
+ * ElementName in an ElementTest or an AttributeName in an AttributeTest.
+ */
+ XPST0008,
+
+ /**
+ * An implementation that does not support the Schema Import Feature
+ * must raise a static error if a Prolog contains a schema import.
+ */
+ XQST0009,
+
+ /**
+ * An implementation must raise a static error if it encounters
+ * a reference to an axis that it does not support.
+ */
+ XPST0010,
+
+ /**
+ * It is a static error if the set of definitions contained in all
+ * schemas imported by a Prolog do not satisfy the conditions for
+ * schema validity specified in Sections 3 and 5 of [XML Schema]
+ * Part 1--i.e., each definition must be valid, complete, and unique.
+ */
+ XQST0012,
+
+ /**
+ * It is a static error if an implementation recognizes a pragma
+ * but determines that its content is invalid.
+ */
+ XQST0013,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0014,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0015,
+
+ /**
+ * An implementation that does not support the Module Feature raises
+ * a static error if it encounters a module declaration or a module
+ * import.
+ */
+ XQST0016,
+
+ /**
+ * It is a static error if the expanded QName and number of arguments
+ * in a function call do not match the name and arity of a function
+ * signature in the static context.
+ */
+ XPST0017,
+
+ /**
+ * It is a type error if the result of the last step in a path expression
+ * contains both nodes and atomic values.
+ */
+ XPTY0018,
+
+ /**
+ * It is a type error if the result of a step (other than the last
+ * step) in a path expression contains an atomic value.
+ */
+ XPTY0019,
+
+ /**
+ * It is a type error if, in an axis step, the context item is not
+ * a node.
+ */
+ XPTY0020,
+
+ /**
+ * (Not currently used.)
+ */
+ XPDY0021,
+
+ /**
+ * It is a static error if the value of a namespace declaration
+ * attribute is not a URILiteral.
+ */
+ XQST0022,
+
+ /**
+ * (Not currently used.)
+ */
+ XQTY0023,
+
+ /**
+ * It is a type error if the content sequence in an element constructor
+ * contains an attribute node following a node that is not an attribute
+ * node.
+ */
+ XQTY0024,
+
+ /**
+ * It is a dynamic error if any attribute of a constructed element
+ * does not have a name that is distinct from the names of all other
+ * attributes of the constructed element.
+ */
+ XQDY0025,
+
+ /**
+ * It is a dynamic error if the result of the content expression
+ * of a computed processing instruction constructor contains the
+ * string "?&gt;".
+ */
+ XQDY0026,
+
+ /**
+ * In a validate expression, it is a dynamic error if the root element
+ * information item in the PSVI resulting from validation does not
+ * have the expected validity property: valid if validation mode
+ * is strict, or either valid or notKnown if validation mode is
+ * lax.
+ */
+ XQDY0027,
+
+ /**
+ * (Not currently used.)
+ */
+ XQTY0028,
+
+ /**
+ * (Not currently used.)
+ */
+ XQDY0029,
+
+ /**
+ * It is a type error if the argument of a validate expression does
+ * not evaluate to exactly one document or element node.
+ */
+ XQTY0030,
+
+ /**
+ * It is a static error if the version number specified in a version
+ * declaration is not supported by the implementation.
+ */
+ XQST0031,
+
+ /**
+ * A static error is raised if a Prolog contains more than one base
+ * URI declaration.
+ */
+ XQST0032,
+
+ /**
+ * It is a static error if a module contains multiple bindings for
+ * the same namespace prefix.
+ */
+ XQST0033,
+
+ /**
+ * It is a static error if multiple functions declared or imported
+ * by a module have the number of arguments and their expanded QNames
+ * are equal (as defined by the eq operator).
+ */
+ XQST0034,
+
+ /**
+ * It is a static error to import two schema components that both
+ * define the same name in the same symbol space and in the same
+ * scope.
+ */
+ XQST0035,
+
+ /**
+ * It is a static error to import a module if the importing module's
+ * in-scope schema types do not include definitions for the schema
+ * type names that appear in the declarations of variables and functions
+ * (whether in an argument type or return type) that are present
+ * in the imported module and are referenced in the importing module.
+ */
+ XQST0036,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0037,
+
+ /**
+ * It is a static error if a Prolog contains more than one default
+ * collation declaration, or the value specified by a default collation
+ * declaration is not present in statically known collations.
+ */
+ XQST0038,
+
+ /**
+ * It is a static error for a function declaration to have more
+ * than one parameter with the same name.
+ */
+ XQST0039,
+
+ /**
+ * It is a static error if the attributes specified by a direct
+ * element constructor do not have distinct expanded QNames.
+ */
+ XQST0040,
+
+ /**
+ * It is a dynamic error if the value of the name expression in
+ * a computed processing instruction constructor cannot be cast
+ * to the type xs:NCName.
+ */
+ XQDY0041,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0042,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0043,
+
+ /**
+ * It is a dynamic error if the node-name property of the node constructed
+ * by a computed attribute constructor is in the namespace http://www.w3.org/2000/xmlns/
+ * (corresponding to namespace prefix xmlns), or is in no namespace
+ * and has local name xmlns.
+ */
+ XQDY0044,
+
+ /**
+ * It is a static error if the function name in a function declaration
+ * is in one of the following namespaces: http://www.w3.org/XML/1998/namespace,
+ * http://www.w3.org/2001/XMLSchema, http://www.w3.org/2001/XMLSchema-instance,
+ * http://www.w3.org/2005/xpath-functions.
+ */
+ XQST0045,
+
+ /**
+ * An implementation MAY raise a static error if the value of a
+ * URILiteral is of nonzero length and is not in the lexical space
+ * of xs:anyURI.
+ */
+ XQST0046,
+
+ /**
+ * It is a static error if multiple module imports in the same Prolog
+ * specify the same target namespace.
+ */
+ XQST0047,
+
+ /**
+ * It is a static error if a function or variable declared in a
+ * library module is not in the target namespace of the library
+ * module.
+ */
+ XQST0048,
+
+ /**
+ * It is a static error if two or more variables declared or imported
+ * by a module have equal expanded QNames (as defined by the eq
+ * operator.)
+ */
+ XQST0049,
+
+ /**
+ * It is a dynamic error if the dynamic type of the operand of a
+ * treat expression does not match the sequence type specified by
+ * the treat expression. This error might also be raised by a path
+ * expression beginning with "/" or "//" if the context node is
+ * not in a tree that is rooted at a document node. This is because
+ * a leading "/" or "//" in a path expression is an abbreviation
+ * for an initial step that includes the clause treat as document-node().
+ */
+ XPDY0050,
+
+ /**
+ * It is a static error if a QName that is used as an AtomicType
+ * in a SequenceType is not defined in the in-scope schema types
+ * as an atomic type.
+ */
+ XPST0051,
+
+ /**
+ * (Not currently used.)
+ */
+ XQDY0052,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0053,
+
+ /**
+ * It is a static error if a variable depends on itself.
+ */
+ XQST0054,
+
+ /**
+ * It is a static error if a Prolog contains more than one copy-namespaces
+ * declaration.
+ */
+ XQST0055,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0056,
+
+ /**
+ * It is a static error if a schema import binds a namespace prefix
+ * but does not specify a target namespace other than a zero-length
+ * string.
+ */
+ XQST0057,
+
+ /**
+ * It is a static error if multiple schema imports specify the same
+ * target namespace.
+ */
+ XQST0058,
+
+ /**
+ * It is a static error if an implementation is unable to process
+ * a schema or module import by finding a schema or module with
+ * the specified target namespace.
+ */
+ XQST0059,
+
+ /**
+ * It is a static error if the name of a function in a function
+ * declaration is not in a namespace (expanded QName has a null
+ * namespace URI).
+ */
+ XQST0060,
+
+ /**
+ * It is a dynamic error if the operand of a validate expression
+ * is a document node whose children do not consist of exactly one
+ * element node and zero or more comment and processing instruction
+ * nodes, in any order.
+ */
+ XQDY0061,
+
+ /**
+ * (Not currently used.)
+ */
+ XQDY0062,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0063,
+
+ /**
+ * It is a dynamic error if the value of the name expression in
+ * a computed processing instruction constructor is equal to "XML"
+ * (in any combination of upper and lower case).
+ */
+ XQDY0064,
+
+ /**
+ * A static error is raised if a Prolog contains more than one ordering
+ * mode declaration.
+ */
+ XQST0065,
+
+ /**
+ * A static error is raised if a Prolog contains more than one default
+ * element/type namespace declaration, or more than one default
+ * function namespace declaration.
+ */
+ XQST0066,
+
+ /**
+ * A static error is raised if a Prolog contains more than one construction
+ * declaration.
+ */
+ XQST0067,
+
+ /**
+ * A static error is raised if a Prolog contains more than one boundary-space
+ * declaration.
+ */
+ XQST0068,
+
+ /**
+ * A static error is raised if a Prolog contains more than one empty
+ * order declaration.
+ */
+ XQST0069,
+
+ /**
+ * A static error is raised if a namespace URI is bound to the predefined
+ * prefix xmlns, or if a namespace URI other than http://www.w3.org/XML/1998/namespace
+ * is bound to the prefix xml, or if the prefix xml is bound to
+ * a namespace URI other than http://www.w3.org/XML/1998/namespace.
+ */
+ XQST0070,
+
+ /**
+ * A static error is raised if the namespace declaration attributes
+ * of a direct element constructor do not have distinct names.
+ */
+ XQST0071,
+
+ /**
+ * It is a dynamic error if the result of the content expression
+ * of a computed comment constructor contains two adjacent hyphens
+ * or ends with a hyphen.
+ */
+ XQDY0072,
+
+ /**
+ * It is a static error if the graph of module imports contains
+ * a cycle (that is, if there exists a sequence of modules M1 ...
+ * Mn such that each Mi imports Mi+1 and Mn imports M1), unless
+ * all the modules in the cycle share a common namespace.
+ */
+ XQST0073,
+
+ /**
+ * It is a dynamic error if the value of the name expression in
+ * a computed element or attribute constructor cannot be converted
+ * to an expanded QName (for example, because it contains a namespace
+ * prefix not found in statically known namespaces.)
+ */
+ XQDY0074,
+
+ /**
+ * An implementation that does not support the Validation Feature
+ * must raise a static error if it encounters a validate expression.
+ */
+ XQST0075,
+
+ /**
+ * It is a static error if a collation subclause in an order by
+ * clause of a FLWOR expression does not identify a collation that
+ * is present in statically known collations.
+ */
+ XQST0076,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0077,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0078,
+
+ /**
+ * It is a static error if an extension expression contains neither
+ * a pragma that is recognized by the implementation nor an expression
+ * enclosed in curly braces.
+ */
+ XQST0079,
+
+ /**
+ * It is a static error if the target type of a cast or castable
+ * expression is xs:NOTATION or xs:anyAtomicType.
+ */
+ XPST0080,
+
+ /**
+ * It is a static error if a QName used in a query contains a namespace
+ * prefix that cannot be expanded into a namespace URI by using
+ * the statically known namespaces.
+ */
+ XPST0081,
+
+ /**
+ * (Not currently used.)
+ */
+ XQST0082,
+
+ /**
+ * (Not currently used.)
+ */
+ XPST0083,
+
+ /**
+ * It is a dynamic error if the element validated by a validate
+ * statement does not have a top-level element declaration in the
+ * in-scope element declarations, if validation mode is strict.
+ */
+ XQDY0084,
+
+ /**
+ * It is a static error if the namespace URI in a namespace declaration
+ * attribute is a zero-length string, and the implementation does
+ * not support [XML Names 1.1].
+ */
+ XQST0085,
+
+ /**
+ * It is a type error if the typed value of a copied element or
+ * attribute node is namespace-sensitive when construction mode
+ * is preserve and copy-namespaces mode is no-preserve.
+ */
+ XQTY0086,
+
+ /**
+ * It is a static error if the encoding specified in a Version Declaration
+ * does not conform to the definition of EncName specified in [XML
+ * 1.0].
+ */
+ XQST0087,
+
+ /**
+ * It is a static error if the literal that specifies the target
+ * namespace in a module import or a module declaration is of zero
+ * length.
+ */
+ XQST0088,
+
+ /**
+ * It is a static error if a variable bound in a for clause of a
+ * FLWOR expression, and its associated positional variable, do
+ * not have distinct names (expanded QNames).
+ */
+ XQST0089,
+
+ /**
+ * It is a static error if a character reference does not identify
+ * a valid character in the version of XML that is in use.
+ */
+ XQST0090,
+
+ /**
+ * An implementation MAY raise a dynamic error if an xml:id error,
+ * as defined in [XML ID], is encountered during construction of
+ * an attribute named xml:id.
+ */
+ XQDY0091,
+
+ /**
+ * An implementation MAY raise a dynamic error if a constructed
+ * attribute named xml:space has a value other than preserve or
+ * default.
+ */
+ XQDY0092,
+
+ /**
+ * It is a static error to import a module M1 if there exists a
+ * sequence of modules M1 ... Mi ... M1 such that each module directly
+ * depends on the next module in the sequence (informally, if M1
+ * depends on itself through some chain of module dependencies.)
+ */
+ XQST0093,
+
+ /**
+ * Unidentified error.
+ */
+ FOER0000,
+
+ /**
+ * Division by zero.
+ */
+ FOAR0001,
+
+ /**
+ * Numeric operation overflow/underflow.
+ */
+ FOAR0002,
+
+ /**
+ * Input value too large for decimal.
+ */
+ FOCA0001,
+
+ /**
+ * Invalid lexical value.
+ */
+ FOCA0002,
+
+ /**
+ * Input value too large for integer.
+ */
+ FOCA0003,
+
+ /**
+ * NaN supplied as float/double value.
+ */
+ FOCA0005,
+
+ /**
+ * String to be cast to decimal has too many digits of precision.
+ */
+ FOCA0006,
+
+ /**
+ * Code point not valid.
+ */
+ FOCH0001,
+
+ /**
+ * Unsupported collation.
+ */
+ FOCH0002,
+
+ /**
+ * Unsupported normalization form.
+ */
+ FOCH0003,
+
+ /**
+ * Collation does not support collation units.
+ */
+ FOCH0004,
+
+ /**
+ * No context document.
+ */
+ FODC0001,
+
+ /**
+ * Error retrieving resource.
+ */
+ FODC0002,
+
+ /**
+ * Function stability not defined.
+ */
+ FODC0003,
+
+ /**
+ * Invalid argument to fn:collection.
+ */
+ FODC0004,
+
+ /**
+ * Invalid argument to fn:doc or fn:doc-available.
+ */
+ FODC0005,
+
+ /**
+ * Overflow/underflow in date/time operation.
+ */
+ FODT0001,
+
+ /**
+ * Overflow/underflow in duration operation.
+ */
+ FODT0002,
+
+ /**
+ * Invalid timezone value.
+ */
+ FODT0003,
+
+ /**
+ * No namespace found for prefix.
+ */
+ FONS0004,
+
+ /**
+ * Base-uri not defined in the static context.
+ */
+ FONS0005,
+
+ /**
+ * Invalid value for cast/constructor.
+ */
+ FORG0001,
+
+ /**
+ * Invalid argument to fn:resolve-uri().
+ */
+ FORG0002,
+
+ /**
+ * fn:zero-or-one called with a sequence containing more than one
+ * item.
+ */
+ FORG0003,
+
+ /**
+ * fn:one-or-more called with a sequence containing no items.
+ */
+ FORG0004,
+
+ /**
+ * fn:exactly-one called with a sequence containing zero or more
+ * than one item.
+ */
+ FORG0005,
+
+ /**
+ * Invalid argument type.
+ */
+ FORG0006,
+
+ /**
+ * Both arguments to fn:dateTime have a specified timezone.
+ */
+ FORG0008,
+
+ /**
+ * Error in resolving a relative URI against a base URI in fn:resolve-uri.
+ */
+ FORG0009,
+
+ /**
+ * Invalid regular expression. flags
+ */
+ FORX0001,
+
+ /**
+ * Invalid regular expression.
+ */
+ FORX0002,
+
+ /**
+ * Regular expression matches zero-length string.
+ */
+ FORX0003,
+
+ /**
+ * Invalid replacement string.
+ */
+ FORX0004,
+
+ /**
+ * Argument node does not have a typed value.
+ */
+ FOTY0012,
+
+ /**
+ * It is an error if an item in S6 in sequence normalization is
+ * an attribute node or a namespace node.
+ */
+ SENR0001,
+
+ /**
+ * It is an error if the serializer is unable to satisfy the rules
+ * for either a well-formed XML document entity or a well-formed
+ * XML external general parsed entity, or both, except for content
+ * modified by the character expansion phase of serialization.
+ */
+ SERE0003,
+
+ /**
+ * It is an error to specify the doctype-system parameter, or to
+ * specify the standalone parameter with a value other than omit,
+ * if the instance of the data model contains text nodes or multiple
+ * element nodes as children of the root node.
+ */
+ SEPM0004,
+
+ /**
+ * It is an error if the serialized result would contain an NCName
+ * Names that contains a character that is not permitted by the
+ * version of Namespaces in XML specified by the version parameter.
+ */
+ SERE0005,
+
+ /**
+ * It is an error if the serialized result would contain a character
+ * that is not permitted by the version of XML specified by the
+ * version parameter.
+ */
+ SERE0006,
+
+ /**
+ * It is an error if an output encoding other than UTF-8 or UTF-16
+ * is requested and the serializer does not support that encoding.
+ */
+ SESU0007,
+
+ /**
+ * It is an error if a character that cannot be represented in the
+ * encoding that the serializer is using for output appears in a
+ * context where character references are not allowed (for example
+ * if the character occurs in the name of an element).
+ */
+ SERE0008,
+
+ /**
+ * It is an error if the omit-xml-declaration parameter has the
+ * value yes, and the standalone attribute has a value other than
+ * omit; or the version parameter has a value other than 1.0 and
+ * the doctype-system parameter is specified.
+ */
+ SEPM0009,
+
+ /**
+ * It is an error if the output method is xml, the value of the
+ * undeclare-prefixes parameter is yes, and the value of the version
+ * parameter is 1.0.
+ */
+ SEPM0010,
+
+ /**
+ * It is an error if the value of the normalization-form parameter
+ * specifies a normalization form that is not supported by the serializer.
+ */
+ SESU0011,
+
+ /**
+ * It is an error if the value of the normalization-form parameter
+ * is fully-normalized and any relevant construct of the result
+ * begins with a combining character.
+ */
+ SERE0012,
+
+ /**
+ * It is an error if the serializer does not support the version
+ * of XML or HTML specified by the version parameter.
+ */
+ SESU0013,
+
+ /**
+ * It is an error to use the HTML output method when characters
+ * which are legal in XML but not in HTML, specifically the control
+ * characters \#x7F-#x9F, appear in the instance of the data model.
+ */
+ SERE0014,
+
+ /**
+ * It is an error to use the HTML output method when &gt; appears within
+ * a processing instruction in the data model instance being serialized.
+ */
+ SERE0015,
+
+ /**
+ * It is a an error if a parameter value is invalid for the defined
+ * domain.
+ */
+ SEPM0016,
+
+ /**
+ * A static error is signaled if an XSLT-defined element is used
+ * in a context where it is not permitted, if a required attribute
+ * is omitted, or if the content of the element does not correspond
+ * to the content that is allowed for the element.
+ */
+ XTSE0010,
+
+ /**
+ * It is a static error if an attribute (other than an attribute
+ * written using curly brackets in a position where an attribute
+ * value template is permitted) contains a value that is not one
+ * of the permitted values for that attribute.
+ */
+ XTSE0020,
+
+ /**
+ * It is a static error to use a reserved namespace in the name
+ * of a named template, a mode, an attribute set, a key, a decimal-format,
+ * a variable or parameter, a stylesheet function, a named output
+ * definition, or a character map.
+ */
+ XTSE0080,
+
+ /**
+ * It is a static error for an element from the XSLT namespace to
+ * have an attribute whose namespace is either null (that is, an
+ * attribute with an unprefixed name) or the XSLT namespace, other
+ * than attributes defined for the element in this document.
+ */
+ XTSE0090,
+
+ /**
+ * The value of the version attribute must be a number: specifically,
+ * it must be a a valid instance of the type xs:decimal as defined
+ * in [XML Schema Part 2].
+ */
+ XTSE0110,
+
+ /**
+ * An xsl:stylesheet element must not have any text node children.
+ */
+ XTSE0120,
+
+ /**
+ * It is a static error if the value of an [xsl:]default-collation
+ * attribute, after resolving against the base URI, contains no
+ * URI that the implementation recognizes as a collation URI.
+ */
+ XTSE0125,
+
+ /**
+ * It is a static error if the xsl:stylesheet element has a child
+ * element whose name has a null namespace URI.
+ */
+ XTSE0130,
+
+ /**
+ * A literal result element that is used as the outermost element
+ * of a simplified stylesheet module must have an xsl:version attribute.
+ */
+ XTSE0150,
+
+ /**
+ * It is a static error if the processor is not able to retrieve
+ * the resource identified by the URI reference [ in the href attribute
+ * of xsl:include or xsl:import] , or if the resource that is retrieved
+ * does not contain a stylesheet module conforming to this specification.
+ */
+ XTSE0165,
+
+ /**
+ * An xsl:include element must be a top-level element.
+ */
+ XTSE0170,
+
+ /**
+ * It is a static error if a stylesheet module directly or indirectly
+ * includes itself.
+ */
+ XTSE0180,
+
+ /**
+ * An xsl:import element must be a top-level element.
+ */
+ XTSE0190,
+
+ /**
+ * The xsl:import element children must precede all other element
+ * children of an xsl:stylesheet element, including any xsl:include
+ * element children and any user-defined data elements.
+ */
+ XTSE0200,
+
+ /**
+ * It is a static error if a stylesheet module directly or indirectly
+ * imports itself.
+ */
+ XTSE0210,
+
+ /**
+ * It is a static error if an xsl:import-schema element that contains
+ * an xs:schema element has a schema-location attribute, or if it
+ * has a namespace attribute that conflicts with the target namespace
+ * of the contained schema.
+ */
+ XTSE0215,
+
+ /**
+ * It is a static error if the synthetic schema document does not
+ * satisfy the constraints described in [XML Schema Part 1] (section
+ * 5.1, Errors in Schema Construction and Structure). This includes,
+ * without loss of generality, conflicts such as multiple definitions
+ * of the same name.
+ */
+ XTSE0220,
+
+ /**
+ * Within an XSLT element that is required to be empty, any content
+ * other than comments or processing instructions, including any
+ * whitespace text node preserved using the xml:space="preserve"
+ * attribute, is a static error.
+ */
+ XTSE0260,
+
+ /**
+ * It is a static error if there is a stylesheet module in the stylesheet
+ * that specifies input-type-annotations="strip" and another stylesheet
+ * module that specifies input-type-annotations="preserve".
+ */
+ XTSE0265,
+
+ /**
+ * In the case of a prefixed QName used as the value of an attribute
+ * in the stylesheet, or appearing within an XPath expression in
+ * the stylesheet, it is a static error if the defining element
+ * has no namespace node whose name matches the prefix of the QName.
+ */
+ XTSE0280,
+
+ /**
+ * Where an attribute is defined to contain a pattern, it is a static
+ * error if the pattern does not match the production Pattern.
+ */
+ XTSE0340,
+
+ /**
+ * It is a static error if an unescaped left curly bracket appears
+ * in a fixed part of an attribute value template without a matching
+ * right curly bracket.
+ */
+ XTSE0350,
+
+ /**
+ * It is a static error if an unescaped right curly bracket occurs
+ * in a fixed part of an attribute value template.
+ */
+ XTSE0370,
+
+ /**
+ * An xsl:template element must have either a match attribute or
+ * a name attribute, or both. An xsl:template element that has no
+ * match attribute must have no mode attribute and no priority attribute.
+ */
+ XTSE0500,
+
+ /**
+ * The value of this attribute [the priority attribute of the xsl:template
+ * element] must conform to the rules for the xs:decimal type defined
+ * in [XML Schema Part 2]. Negative values are permitted..
+ */
+ XTSE0530,
+
+ /**
+ * It is a static error if the list [of modes in the mode attribute
+ * of xsl:template] is empty, if the same token is included more
+ * than once in the list, if the list contains an invalid token,
+ * or if the token \#all appears together with any other value.
+ */
+ XTSE0550,
+
+ /**
+ * It is a static error if two parameters of a template or of a
+ * stylesheet function have the same name.
+ */
+ XTSE0580,
+
+ /**
+ * It is a static error if a variable-binding element has a select
+ * attribute and has non-empty content.
+ */
+ XTSE0620,
+
+ /**
+ * It is a static error if a stylesheet contains more than one binding
+ * of a global variable with the same name and same import precedence,
+ * unless it also contains another binding with the same name and
+ * higher import precedence.
+ */
+ XTSE0630,
+
+ /**
+ * It is a static error if a stylesheet contains an xsl:call-template
+ * instruction whose name attribute does not match the name attribute
+ * of any xsl:template in the stylesheet.
+ */
+ XTSE0650,
+
+ /**
+ * It is a static error if a stylesheet contains more than one template
+ * with the same name and the same import precedence, unless it
+ * also contains a template with the same name and higher import
+ * precedence.
+ */
+ XTSE0660,
+
+ /**
+ * It is a static error if a single xsl:call-template, xsl:apply-templates,
+ * xsl:apply-imports, or xsl:next-match element contains two or
+ * more xsl:with-param elements with matching name attributes.
+ */
+ XTSE0670,
+
+ /**
+ * In the case of xsl:call-template, it is a static error to pass
+ * a non-tunnel parameter named x to a template that does not have
+ * a template parameter named x, unless backwards compatible behavior
+ * is enabled for the xsl:call-template instruction.
+ */
+ XTSE0680,
+
+ /**
+ * It is a static error if a template that is invoked using xsl:call-template
+ * declares a template parameter specifying required="yes" and not
+ * specifying tunnel="yes", if no value for this parameter is supplied
+ * by the calling instruction.
+ */
+ XTSE0690,
+
+ /**
+ * It is a static error if the value of the use-attribute-sets attribute
+ * of an xsl:copy, xsl:element, or xsl:attribute-set element, or
+ * the xsl:use-attribute-sets attribute of a literal result element,
+ * is not a whitespace-separated sequence of QNames, or if it contains
+ * a QName that does not match the name attribute of any xsl:attribute-set
+ * declaration in the stylesheet.
+ */
+ XTSE0710,
+
+ /**
+ * It is a static error if an xsl:attribute-set element directly
+ * or indirectly references itself via the names contained in the
+ * use-attribute-sets attribute.
+ */
+ XTSE0720,
+
+ /**
+ * A stylesheet function must have a prefixed name, to remove any
+ * risk of a clash with a function in the default function namespace.
+ * It is a static error if the name has no prefix.
+ */
+ XTSE0740,
+
+ /**
+ * Because arguments to a stylesheet function call must all be specified,
+ * the xsl:param elements within an xsl:function element must not
+ * specify a default value: this means they must be empty, and must
+ * not have a select attribute.
+ */
+ XTSE0760,
+
+ /**
+ * It is a static error for a stylesheet to contain two or more
+ * functions with the same expanded-QName, the same arity, and the
+ * same import precedence, unless there is another function with
+ * the same expanded-QName and arity, and a higher import precedence.
+ */
+ XTSE0770,
+
+ /**
+ * It is a static error if an attribute on a literal result element
+ * is in the XSLT namespace, unless it is one of the attributes
+ * explicitly defined in this specification.
+ */
+ XTSE0805,
+
+ /**
+ * It is a static error if a namespace prefix is used within the
+ * [xsl:]exclude-result-prefixes attribute and there is no namespace
+ * binding in scope for that prefix.
+ */
+ XTSE0808,
+
+ /**
+ * It is a static error if the value \#default is used within the
+ * [xsl:]exclude-result-prefixes attribute and the parent element
+ * of the [xsl:]exclude-result-prefixes attribute has no default
+ * namespace.
+ */
+ XTSE0809,
+
+ /**
+ * It is a static error if there is more than one such declaration
+ * [more than one xsl:namespace-alias declaration] with the same
+ * literal namespace URI and the same import precedence and different
+ * values for the target namespace URI, unless there is also an
+ * xsl:namespace-alias declaration with the same literal namespace
+ * URI and a higher import precedence.
+ */
+ XTSE0810,
+
+ /**
+ * It is a static error if a value other than \#default is specified
+ * for either the stylesheet-prefix or the result-prefix attributes
+ * of the xsl:namespace-alias element when there is no in-scope
+ * binding for that namespace prefix.
+ */
+ XTSE0812,
+
+ /**
+ * It is a static error if the select attribute of the xsl:attribute
+ * element is present unless the element has empty content.
+ */
+ XTSE0840,
+
+ /**
+ * It is a static error if the select attribute of the xsl:value-of
+ * element is present when the content of the element is non-empty,
+ * or if the select attribute is absent when the content is empty.
+ */
+ XTSE0870,
+
+ /**
+ * It is a static error if the select attribute of the xsl:processing-instruction
+ * element is present unless the element has empty content.
+ */
+ XTSE0880,
+
+ /**
+ * It is a static error if the select attribute of the xsl:namespace
+ * element is present when the element has content other than one
+ * or more xsl:fallback instructions, or if the select attribute
+ * is absent when the element has empty content.
+ */
+ XTSE0910,
+
+ /**
+ * It is a static error if the select attribute of the xsl:comment
+ * element is present unless the element has empty content.
+ */
+ XTSE0940,
+
+ /**
+ * It is a type error to use the xsl:copy or xsl:copy-of instruction
+ * to copy a node that has namespace-sensitive content if the copy-namespaces
+ * attribute has the value no and its explicit or implicit validation
+ * attribute has the value preserve. It is also a type error if
+ * either of these instructions (with validation="preserve") is
+ * used to copy an attribute having namespace-sensitive content,
+ * unless the parent element is also copied. A node has namespace-sensitive
+ * content if its typed value contains an item of type xs:QName
+ * or xs:NOTATION or a type derived therefrom. The reason this is
+ * an error is because the validity of the content depends on the
+ * namespace context being preserved.
+ */
+ XTTE0950,
+
+ /**
+ * It is a static error if the value attribute of xsl:number is
+ * present unless the select, level, count, and from attributes
+ * are all absent.
+ */
+ XTSE0975,
+
+ /**
+ * It is a static error if an xsl:sort element with a select attribute
+ * has non-empty content.
+ */
+ XTSE1015,
+
+ /**
+ * It is a static error if an xsl:sort element other than the first
+ * in a sequence of sibling xsl:sort elements has a stable attribute.
+ */
+ XTSE1017,
+
+ /**
+ * It is a static error if an xsl:perform-sort instruction with
+ * a select attribute has any content other than xsl:sort and xsl:fallback
+ * instructions.
+ */
+ XTSE1040,
+
+ /**
+ * It is a static error if the current-group function is used within
+ * a pattern.
+ */
+ XTSE1060,
+
+ /**
+ * It is a static error if the current-grouping-key function is
+ * used within a pattern.
+ */
+ XTSE1070,
+
+ /**
+ * These four attributes [the group-by, group-adjacent, group-starting-with,
+ * and group-ending-with attributes of xsl:for-each-group ] are
+ * mutually exclusive: it is a static error if none of these four
+ * attributes is present, or if more than one of them is present.
+ */
+ XTSE1080,
+
+ /**
+ * It is an error to specify the collation attribute if neither
+ * the group-by attribute nor group-adjacent attribute is specified.
+ */
+ XTSE1090,
+
+ /**
+ * It is a static error if the xsl:analyze-string instruction contains
+ * neither an xsl:matching-substring nor an xsl:non-matching-substring
+ * element.
+ */
+ XTSE1130,
+
+ /**
+ * It is a static error if an xsl:key declaration has a use attribute
+ * and has non-empty content, or if it has empty content and no
+ * use attribute.
+ */
+ XTSE1205,
+
+ /**
+ * It is a static error if the xsl:key declaration has a collation
+ * attribute whose value (after resolving against the base URI)
+ * is not a URI recognized by the implementation as referring to
+ * a collation.
+ */
+ XTSE1210,
+
+ /**
+ * It is a static error if there are several xsl:key declarations
+ * in the stylesheet with the same key name and different effective
+ * collations. Two collations are the same if their URIs are equal
+ * under the rules for comparing xs:anyURI values, or if the implementation
+ * can determine that they are different URIs referring to the same
+ * collation.
+ */
+ XTSE1220,
+
+ /**
+ * It is a static error if a named or unnamed decimal format contains
+ * two conflicting values for the same attribute in different xsl:decimal-format
+ * declarations having the same import precedence, unless there
+ * is another definition of the same attribute with higher import
+ * precedence.
+ */
+ XTSE1290,
+
+ /**
+ * It is a static error if the character specified in the zero-digit
+ * attribute is not a digit or is a digit that does not have the
+ * numeric value zero.
+ */
+ XTSE1295,
+
+ /**
+ * It is a static error if, for any named or unnamed decimal format,
+ * the variables representing characters used in a picture string
+ * do not each have distinct values. These variables are decimal-separator-sign,
+ * grouping-sign, percent-sign, per-mille-sign, digit-zero-sign,
+ * digit-sign, and pattern-separator-sign.
+ */
+ XTSE1300,
+
+ /**
+ * It is a static error if there is no namespace bound to the prefix
+ * on the element bearing the [xsl:]extension-element-prefixes attribute
+ * or, when \#default is specified, if there is no default namespace.
+ */
+ XTSE1430,
+
+ /**
+ * It is a static error if both the [xsl:]type and [xsl:]validation
+ * attributes are present on the xsl:element, xsl:attribute, xsl:copy,
+ * xsl:copy-of, xsl:document, or xsl:result-document instructions,
+ * or on a literal result element.
+ */
+ XTSE1505,
+
+ /**
+ * It is a static error if the value of the type attribute of an
+ * xsl:element, xsl:attribute, xsl:copy, xsl:copy-of, xsl:document,
+ * or xsl:result-document instruction, or the xsl:type attribute
+ * of a literal result element, is not a valid QName, or if it uses
+ * a prefix that is not defined in an in-scope namespace declaration,
+ * or if the QName is not the name of a type definition included
+ * in the in-scope schema components for the stylesheet.
+ */
+ XTSE1520,
+
+ /**
+ * It is a static error if the value of the type attribute of an
+ * xsl:attribute instruction refers to a complex type definition
+ */
+ XTSE1530,
+
+ /**
+ * It is a static error if two xsl:output declarations within an
+ * output definition specify explicit values for the same attribute
+ * (other than cdata-section-elements and use-character-maps), with
+ * the values of the attributes being not equal, unless there is
+ * another xsl:output declaration within the same output definition
+ * that has higher import precedence and that specifies an explicit
+ * value for the same attribute.
+ */
+ XTSE1560,
+
+ /**
+ * The value [of the method attribute on xsl:output ] must (if present)
+ * be a valid QName. If the QName does not have a prefix, then it
+ * identifies a method specified in [XSLT and XQuery Serialization]
+ * and must be one of xml, html, xhtml, or text.
+ */
+ XTSE1570,
+
+ /**
+ * It is a static error if the stylesheet contains two or more character
+ * maps with the same name and the same import precedence, unless
+ * it also contains another character map with the same name and
+ * higher import precedence.
+ */
+ XTSE1580,
+
+ /**
+ * It is a static error if a name in the use-character-maps attribute
+ * of the xsl:output or xsl:character-map elements does not match
+ * the name attribute of any xsl:character-map in the stylesheet.
+ */
+ XTSE1590,
+
+ /**
+ * It is a static error if a character map references itself, directly
+ * or indirectly, via a name in the use-character-maps attribute.
+ */
+ XTSE1600,
+
+ /**
+ * A basic XSLT processor must signal a static error if the stylesheet
+ * includes an xsl:import-schema declaration.
+ */
+ XTSE1650,
+
+ /**
+ * A basic XSLT processor must signal a static error if the stylesheet
+ * includes an [xsl:]type attribute, or an [xsl:]validation or default-validation
+ * attribute with a value other than strip.
+ */
+ XTSE1660,
+
+ /**
+ * It is a type error if the result of evaluating the sequence constructor
+ * cannot be converted to the required type.
+ */
+ XTTE0505,
+
+ /**
+ * It is a type error if an xsl:apply-templates instruction with
+ * no select attribute is evaluated when the context item is not
+ * a node.
+ */
+ XTTE0510,
+
+ /**
+ * It is a type error if the sequence returned by the select expression
+ * [of xsl:apply-templates] contains an item that is not a node.
+ */
+ XTTE0520,
+
+ /**
+ * It is a type error if the supplied value of a variable cannot
+ * be converted to the required type.
+ */
+ XTTE0570,
+
+ /**
+ * It is a type error if the conversion of the supplied value of
+ * a parameter to its required type fails.
+ */
+ XTTE0590,
+
+ /**
+ * If a default value is given explicitly, that is, if there is
+ * either a select attribute or a non-empty sequence constructor,
+ * then it is a type error if the default value cannot be converted
+ * to the required type, using the function conversion rules.
+ */
+ XTTE0600,
+
+ /**
+ * If the as attribute [of xsl:function ] is specified, then the
+ * result evaluated by the sequence constructor (see 5.7 Sequence
+ * Constructors) is converted to the required type, using the function
+ * conversion rules. It is a type error if this conversion fails.
+ */
+ XTTE0780,
+
+ /**
+ * If the value of a parameter to a stylesheet function cannot be
+ * converted to the required type, a type error is signaled.
+ */
+ XTTE0790,
+
+ /**
+ * It is a type error if the xsl:number instruction is evaluated,
+ * with no value or select attribute, when the context item is not
+ * a node.
+ */
+ XTTE0990,
+
+ /**
+ * It is a type error if the result of evaluating the select attribute
+ * of the xsl:number instruction is anything other than a single
+ * node.
+ */
+ XTTE1000,
+
+ /**
+ * If any sort key value, after atomization and any type conversion
+ * required by the data-type attribute, is a sequence containing
+ * more than one item, then the effect depends on whether the xsl:sort
+ * element is evaluated with backwards compatible behavior. With
+ * backwards compatible behavior, the effective sort key value is
+ * the first item in the sequence. In other cases, this is a type
+ * error.
+ */
+ XTTE1020,
+
+ /**
+ * It is a type error if the grouping key evaluated using the group-adjacent
+ * attribute is an empty sequence, or a sequence containing more
+ * than one item.
+ */
+ XTTE1100,
+
+ /**
+ * When the group-starting-with or group-ending-with attribute [of
+ * the xsl:for-each-group instruction] is used, it is a type error
+ * if the result of evaluating the select expression contains an
+ * item that is not a node.
+ */
+ XTTE1120,
+
+ /**
+ * If the validation attribute of an xsl:element, xsl:attribute,
+ * xsl:copy, xsl:copy-of, or xsl:result-document instruction, or
+ * the xsl:validation attribute of a literal result element, has
+ * the effective value strict, and schema validity assessment concludes
+ * that the validity of the element or attribute is invalid or unknown,
+ * a type error occurs. As with other type errors, the error may
+ * be signaled statically if it can be detected statically.
+ */
+ XTTE1510,
+
+ /**
+ * If the validation attribute of an xsl:element, xsl:attribute,
+ * xsl:copy, xsl:copy-of, or xsl:result-document instruction, or
+ * the xsl:validation attribute of a literal result element, has
+ * the effective value strict, and there is no matching top-level
+ * declaration in the schema, then a type error occurs. As with
+ * other type errors, the error may be signaled statically if it
+ * can be detected statically.
+ */
+ XTTE1512,
+
+ /**
+ * If the validation attribute of an xsl:element, xsl:attribute,
+ * xsl:copy, xsl:copy-of, or xsl:result-document instruction, or
+ * the xsl:validation attribute of a literal result element, has
+ * the effective value lax, and schema validity assessment concludes
+ * that the element or attribute is invalid, a type error occurs.
+ * As with other type errors, the error may be signaled statically
+ * if it can be detected statically.
+ */
+ XTTE1515,
+
+ /**
+ * It is a type error if an [xsl:]type attribute is defined for
+ * a constructed element or attribute, and the outcome of schema
+ * validity assessment against that type is that the validity property
+ * of that element or attribute information item is other than valid.
+ */
+ XTTE1540,
+
+ /**
+ * A type error occurs if a type or validation attribute is defined
+ * (explicitly or implicitly) for an instruction that constructs
+ * a new attribute node, if the effect of this is to cause the attribute
+ * value to be validated against a type that is derived from, or
+ * constructed by list or union from, the primitive types xs:QName
+ * or xs:NOTATION.
+ */
+ XTTE1545,
+
+ /**
+ * A type error occurs [when a document node is validated] unless
+ * the children of the document node comprise exactly one element
+ * node, no text nodes, and zero or more comment and processing
+ * instruction nodes, in any order.
+ */
+ XTTE1550,
+
+ /**
+ * It is a type error if, when validating a document node, document-level
+ * constraints are not satisfied. These constraints include identity
+ * constraints (xs:unique, xs:key, and xs:keyref) and ID/IDREF constraints.
+ */
+ XTTE1555,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of an attribute written using curly brackets, in a position where
+ * an attribute value template is permitted, is a value that is
+ * not one of the permitted values for that attribute. If the processor
+ * is able to detect the error statically (for example, when any
+ * XPath expressions within the curly brackets can be evaluated
+ * statically), then the processor may optionally signal this as
+ * a static error.
+ */
+ XTDE0030,
+
+ /**
+ * It is a non-recoverable dynamic error if the invocation of the
+ * stylesheet specifies a template name that does not match the
+ * expanded-QName of a named template defined in the stylesheet.
+ */
+ XTDE0040,
+
+ /**
+ * It is a non-recoverable dynamic error if the invocation of the
+ * stylesheet specifies an initial mode (other than the default
+ * mode) that does not match the expanded-QName in the mode attribute
+ * of any template defined in the stylesheet.
+ */
+ XTDE0045,
+
+ /**
+ * It is a non-recoverable dynamic error if the invocation of the
+ * stylesheet specifies both an initial mode and an initial template.
+ */
+ XTDE0047,
+
+ /**
+ * It is a non-recoverable dynamic error if the stylesheet that
+ * is invoked declares a visible stylesheet parameter with required="yes"
+ * and no value for this parameter is supplied during the invocation
+ * of the stylesheet. A stylesheet parameter is visible if it is
+ * not masked by another global variable or parameter with the same
+ * name and higher import precedence.
+ */
+ XTDE0050,
+
+ /**
+ * It is a non-recoverable dynamic error if the initial template
+ * defines a template parameter that specifies required="yes".
+ */
+ XTDE0060,
+
+ /**
+ * If an implementation does not support backwards-compatible behavior,
+ * then it is a non-recoverable dynamic error if any element is
+ * evaluated that enables backwards-compatible behavior.
+ */
+ XTDE0160,
+
+ /**
+ * It is a recoverable dynamic error if this [the process of finding
+ * an xsl:strip-space or xsl:preserve-space declaration to match
+ * an element in the source document] leaves more than one match,
+ * unless all the matched declarations are equivalent (that is,
+ * they are all xsl:strip-space or they are all xsl:preserve-space).
+ * Action: The optional recovery action is to select, from the matches
+ * that are left, the one that occurs last in declaration order.
+ */
+ XTRE0270,
+
+ /**
+ * Where the result of evaluating an XPath expression (or an attribute
+ * value template) is required to be a lexical QName, then unless
+ * otherwise specified it is a non-recoverable dynamic error if
+ * the defining element has no namespace node whose name matches
+ * the prefix of the lexical QName. This error may be signaled as
+ * a static error if the value of the expression can be determined
+ * statically.
+ */
+ XTDE0290,
+
+ /**
+ * It is a non-recoverable dynamic error if the result sequence
+ * used to construct the content of an element node contains a namespace
+ * node or attribute node that is preceded in the sequence by a
+ * node that is neither a namespace node nor an attribute node.
+ */
+ XTDE0410,
+
+ /**
+ * It is a non-recoverable dynamic error if the result sequence
+ * used to construct the content of a document node contains a namespace
+ * node or attribute node.
+ */
+ XTDE0420,
+
+ /**
+ * It is a non-recoverable dynamic error if the result sequence
+ * contains two or more namespace nodes having the same name but
+ * different string values (that is, namespace nodes that map the
+ * same prefix to different namespace URIs).
+ */
+ XTDE0430,
+
+ /**
+ * It is a non-recoverable dynamic error if the result sequence
+ * contains a namespace node with no name and the element node being
+ * constructed has a null namespace URI (that is, it is an error
+ * to define a default namespace when the element is in no namespace).
+ */
+ XTDE0440,
+
+ /**
+ * It is a non-recoverable dynamic error if namespace fixup is performed
+ * on an element that contains among the typed values of the element
+ * and its attributes two values of type xs:QName or xs:NOTATION
+ * containing conflicting namespace prefixes, that is, two values
+ * that use the same prefix to refer to different namespace URIs.
+ */
+ XTDE0485,
+
+ /**
+ * It is a recoverable dynamic error if the conflict resolution
+ * algorithm for template rules leaves more than one matching template
+ * rule. Action: The optional recovery action is to select, from
+ * the matching template rules that are left, the one that occurs
+ * last in declaration order.
+ */
+ XTRE0540,
+
+ /**
+ * It is a non-recoverable dynamic error if xsl:apply-imports or
+ * xsl:next-match is evaluated when the current template rule is
+ * null.
+ */
+ XTDE0560,
+
+ /**
+ * If an optional parameter has no select attribute and has an empty
+ * sequence constructor, and if there is an as attribute, then the
+ * default value of the parameter is an empty sequence. If the empty
+ * sequence is not a valid instance of the required type defined
+ * in the as attribute, then the parameter is treated as a required
+ * parameter, which means that it is a non-recoverable dynamic error
+ * if the caller supplies no value for the parameter.
+ */
+ XTDE0610,
+
+ /**
+ * In general, a circularity in a stylesheet is a non-recoverable
+ * dynamic error.
+ */
+ XTDE0640,
+
+ /**
+ * In other cases, [with xsl:apply-templates, xsl:apply-imports,
+ * and xsl:next-match, or xsl:call-template with tunnel parameters]
+ * it is a non-recoverable dynamic error if the template that is
+ * invoked declares a template parameter with required="yes" and
+ * no value for this parameter is supplied by the calling instruction.
+ */
+ XTDE0700,
+
+ /**
+ * It is a recoverable dynamic error if the name of a constructed
+ * attribute is xml:space and the value is not either default or
+ * preserve. Action: The optional recovery action is to construct
+ * the attribute with the value as requested.
+ */
+ XTRE0795,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the name attribute [of the xsl:element instruction] is not
+ * a lexical QName.
+ */
+ XTDE0820,
+
+ /**
+ * In the case of an xsl:element instruction with no namespace attribute,
+ * it is a non-recoverable dynamic error if the effective value
+ * of the name attribute is a QName whose prefix is not declared
+ * in an in-scope namespace declaration for the xsl:element instruction.
+ */
+ XTDE0830,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the namespace attribute [of the xsl:element instruction] is
+ * not in the lexical space of the xs:anyURI data type.
+ */
+ XTDE0835,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the name attribute [of an xsl:attribute instruction] is not
+ * a lexical QName.
+ */
+ XTDE0850,
+
+ /**
+ * In the case of an xsl:attribute instruction with no namespace
+ * attribute, it is a non-recoverable dynamic error if the effective
+ * value of the name attribute is the string xmlns.
+ */
+ XTDE0855,
+
+ /**
+ * In the case of an xsl:attribute instruction with no namespace
+ * attribute, it is a non-recoverable dynamic error if the effective
+ * value of the name attribute is a lexical QName whose prefix is
+ * not declared in an in-scope namespace declaration for the xsl:attribute
+ * instruction.
+ */
+ XTDE0860,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the namespace attribute [of the xsl:attribute instruction]
+ * is not in the lexical space of the xs:anyURI data type.
+ */
+ XTDE0865,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the name attribute [of the xsl:processing-instruction instruction]
+ * is not both an NCName Names and a PITarget XML.
+ */
+ XTDE0890,
+
+ /**
+ * It is a non-recoverable dynamic error if the string value of
+ * the new namespace node [created using xsl:namespace] is not valid
+ * in the lexical space of the data type xs:anyURI. [see ERR XTDE0835]
+ */
+ XTDE0905,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the name attribute [of the xsl:namespace instruction] is neither
+ * a zero-length string nor an NCName Names, or if it is xmlns.
+ */
+ XTDE0920,
+
+ /**
+ * It is a non-recoverable dynamic error if the xsl:namespace instruction
+ * generates a namespace node whose name is xml and whose string
+ * value is not http://www.w3.org/XML/1998/namespace, or a namespace
+ * node whose string value is http://www.w3.org/XML/1998/namespace
+ * and whose name is not xml.
+ */
+ XTDE0925,
+
+ /**
+ * It is a non-recoverable dynamic error if evaluating the select
+ * attribute or the contained sequence constructor of an xsl:namespace
+ * instruction results in a zero-length string.
+ */
+ XTDE0930,
+
+ /**
+ * It is a non-recoverable dynamic error if any undiscarded item
+ * in the atomized sequence supplied as the value of the value attribute
+ * of xsl:number cannot be converted to an integer, or if the resulting
+ * integer is less than 0 (zero).
+ */
+ XTDE0980,
+
+ /**
+ * It is a non-recoverable dynamic error if, for any sort key component,
+ * the set of sort key values evaluated for all the items in the
+ * initial sequence, after any type conversion requested, contains
+ * a pair of ordinary values for which the result of the XPath lt
+ * operator is an error.
+ */
+ XTDE1030,
+
+ /**
+ * It is a non-recoverable dynamic error if the collation attribute
+ * of xsl:sort (after resolving against the base URI) is not a URI
+ * that is recognized by the implementation as referring to a collation.
+ */
+ XTDE1035,
+
+ /**
+ * It is a non-recoverable dynamic error if the collation URI specified
+ * to xsl:for-each-group (after resolving against the base URI)
+ * is a collation that is not recognized by the implementation.
+ * (For notes, [see ERR XTDE1035].)
+ */
+ XTDE1110,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the regex attribute [of the xsl:analyze-string instruction]
+ * does not conform to the required syntax for regular expressions,
+ * as specified in [Functions and Operators]. If the regular expression
+ * is known statically (for example, if the attribute does not contain
+ * any expressions enclosed in curly brackets) then the processor
+ * may signal the error as a static error.
+ */
+ XTDE1140,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the flags attribute [of the xsl:analyze-string instruction]
+ * has a value other than the values defined in [Functions and Operators].
+ * If the value of the attribute is known statically (for example,
+ * if the attribute does not contain any expressions enclosed in
+ * curly brackets) then the processor may signal the error as a
+ * static error.
+ */
+ XTDE1145,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the regex attribute [of the xsl:analyze-string instruction]
+ * is a regular expression that matches a zero-length string: or
+ * more specifically, if the regular expression $r and flags $f
+ * are such that matches("", $r, $f) returns true. If the regular
+ * expression is known statically (for example, if the attribute
+ * does not contain any expressions enclosed in curly brackets)
+ * then the processor may signal the error as a static error.
+ */
+ XTDE1150,
+
+ /**
+ * When a URI reference [supplied to the document function] contains
+ * a fragment identifier, it is a recoverable dynamic error if the
+ * media type is not one that is recognized by the processor, or
+ * if the fragment identifier does not conform to the rules for
+ * fragment identifiers for that media type, or if the fragment
+ * identifier selects something other than a sequence of nodes (for
+ * example, if it selects a range of characters within a text node).
+ * Action: The optional recovery action is to ignore the fragment
+ * identifier and return the document node.
+ */
+ XTRE1160,
+
+ /**
+ * It is a non-recoverable dynamic error if a URI [supplied in the
+ * first argument to the unparsed-text function] contains a fragment
+ * identifier, or if it cannot be used to retrieve a resource containing
+ * text.
+ */
+ XTDE1170,
+
+ /**
+ * It is a non-recoverable dynamic error if a resource [retrieved
+ * using the unparsed-text function] contains octets that cannot
+ * be decoded into Unicode characters using the specified encoding,
+ * or if the resulting characters are not permitted XML characters.
+ * This includes the case where the processor does not support the
+ * requested encoding.
+ */
+ XTDE1190,
+
+ /**
+ * It is a non-recoverable dynamic error if the second argument
+ * of the unparsed-text function is omitted and the processor cannot
+ * infer the encoding using external information and the encoding
+ * is not UTF-8.
+ */
+ XTDE1200,
+
+ /**
+ * It is a non-recoverable dynamic error if the value [of the first
+ * argument to the key function] is not a valid QName, or if there
+ * is no namespace declaration in scope for the prefix of the QName,
+ * or if the name obtained by expanding the QName is not the same
+ * as the expanded name of any xsl:key declaration in the stylesheet.
+ * If the processor is able to detect the error statically (for
+ * example, when the argument is supplied as a string literal),
+ * then the processor may optionally signal this as a static error.
+ */
+ XTDE1260,
+
+ /**
+ * It is a non-recoverable dynamic error to call the key function
+ * with two arguments if there is no context node, or if the root
+ * of the tree containing the context node is not a document node;
+ * or to call the function with three arguments if the root of the
+ * tree containing the node supplied in the third argument is not
+ * a document node.
+ */
+ XTDE1270,
+
+ /**
+ * It is a non-recoverable dynamic error if the name specified as
+ * the $decimal-format-name argument [ to the format-number function]
+ * is not a valid QName, or if its prefix has not been declared
+ * in an in-scope namespace declaration, or if the stylesheet does
+ * not contain a declaration of a decimal-format with a matching
+ * expanded-QName. If the processor is able to detect the error
+ * statically (for example, when the argument is supplied as a string
+ * literal), then the processor may optionally signal this as a
+ * static error.
+ */
+ XTDE1280,
+
+ /**
+ * The picture string [supplied to the format-number function] must
+ * conform to the following rules. [ See full specification.] It
+ * is a non-recoverable dynamic error if the picture string does
+ * not satisfy these rules.
+ */
+ XTDE1310,
+
+ /**
+ * It is a non-recoverable dynamic error if the syntax of the picture
+ * [used for date/time formatting] is incorrect.
+ */
+ XTDE1340,
+
+ /**
+ * It is a non-recoverable dynamic error if a component specifier
+ * within the picture [used for date/time formatting] refers to
+ * components that are not available in the given type of $value,
+ * for example if the picture supplied to the format-time refers
+ * to the year, month, or day component.
+ */
+ XTDE1350,
+
+ /**
+ * If the current function is evaluated within an expression that
+ * is evaluated when the context item is undefined, a non-recoverable
+ * dynamic error occurs.
+ */
+ XTDE1360,
+
+ /**
+ * It is a non-recoverable dynamic error if the unparsed-entity-uri
+ * function is called when there is no context node, or when the
+ * root of the tree containing the context node is not a document
+ * node.
+ */
+ XTDE1370,
+
+ /**
+ * It is a non-recoverable dynamic error if the unparsed-entity-public-id
+ * function is called when there is no context node, or when the
+ * root of the tree containing the context node is not a document
+ * node.
+ */
+ XTDE1380,
+
+ /**
+ * It is a non-recoverable dynamic error if the value [supplied
+ * as the $property-name argument to the system-property function]
+ * is not a valid QName, or if there is no namespace declaration
+ * in scope for the prefix of the QName. If the processor is able
+ * to detect the error statically (for example, when the argument
+ * is supplied as a string literal), then the processor may optionally
+ * signal this as a static error.
+ */
+ XTDE1390,
+
+ /**
+ * When a transformation is terminated by use of xsl:message terminate="yes",
+ * the effect is the same as when a non-recoverable dynamic error
+ * occurs during the transformation.
+ */
+ XTMM9000,
+
+ /**
+ * It is a non-recoverable dynamic error if the argument [passed
+ * to the function-available function] does not evaluate to a string
+ * that is a valid QName, or if there is no namespace declaration
+ * in scope for the prefix of the QName. If the processor is able
+ * to detect the error statically (for example, when the argument
+ * is supplied as a string literal), then the processor may optionally
+ * signal this as a static error.
+ */
+ XTDE1400,
+
+ /**
+ * It is a non-recoverable dynamic error if the arguments supplied
+ * to a call on an extension function do not satisfy the rules defined
+ * for that particular extension function, or if the extension function
+ * reports an error, or if the result of the extension function
+ * cannot be converted to an XPath value.
+ */
+ XTDE1420,
+
+ /**
+ * When backwards compatible behavior is enabled, it is a non-recoverable
+ * dynamic error to evaluate an extension function call if no implementation
+ * of the extension function is available.
+ */
+ XTDE1425,
+
+ /**
+ * It is a non-recoverable dynamic error if the argument [passed
+ * to the type-available function] does not evaluate to a string
+ * that is a valid QName, or if there is no namespace declaration
+ * in scope for the prefix of the QName. If the processor is able
+ * to detect the error statically (for example, when the argument
+ * is supplied as a string literal), then the processor may optionally
+ * signal this as a static error.
+ */
+ XTDE1428,
+
+ /**
+ * It is a non-recoverable dynamic error if the argument [passed
+ * to the element-available function] does not evaluate to a string
+ * that is a valid QName, or if there is no namespace declaration
+ * in scope for the prefix of the QName. If the processor is able
+ * to detect the error statically (for example, when the argument
+ * is supplied as a string literal), then the processor may optionally
+ * signal this as a static error.
+ */
+ XTDE1440,
+
+ /**
+ * When a processor performs fallback for an extension instruction
+ * that is not recognized, if the instruction element has one or
+ * more xsl:fallback children, then the content of each of the xsl:fallback
+ * children must be evaluated; it is a non-recoverable dynamic error
+ * if it has no xsl:fallback children.
+ */
+ XTDE1450,
+
+ /**
+ * It is a non-recoverable dynamic error if the effective value
+ * of the format attribute [of an xsl:result-document element] is
+ * not a valid lexical QName, or if it does not match the expanded-QName
+ * of an output definition in the stylesheet. If the processor is
+ * able to detect the error statically (for example, when the format
+ * attribute contains no curly brackets), then the processor may
+ * optionally signal this as a static error.
+ */
+ XTDE1460,
+
+ /**
+ * It is a non-recoverable dynamic error to evaluate the xsl:result-document
+ * instruction in temporary output state.
+ */
+ XTDE1480,
+
+ /**
+ * It is a non-recoverable dynamic error for a transformation to
+ * generate two or more final result trees with the same URI.
+ */
+ XTDE1490,
+
+ /**
+ * It is a recoverable dynamic error for a transformation to generate
+ * two or more final result trees with URIs that identify the same
+ * physical resource. The optional recovery action is implementation-dependent,
+ * since it may be impossible for the processor to detect the error.
+ */
+ XTRE1495,
+
+ /**
+ * It is a recoverable dynamic error for a stylesheet to write to
+ * an external resource and read from the same resource during a
+ * single transformation, whether or not the same URI is used to
+ * access the resource in both cases. Action: The optional recovery
+ * action is implementation-dependent: implementations are not required
+ * to detect the error condition. Note that if the error is not
+ * detected, it is undefined whether the document that is read from
+ * the resource reflects its state before or after the result tree
+ * is written.
+ */
+ XTRE1500,
+
+ /**
+ * It is a recoverable dynamic error if an xsl:value-of or xsl:text
+ * instruction specifies that output escaping is to be disabled
+ * and the implementation does not support this. Action: The optional
+ * recovery action is to ignore the disable-output-escaping attribute.
+ */
+ XTRE1620,
+
+ /**
+ * It is a recoverable dynamic error if an xsl:value-of or xsl:text
+ * instruction specifies that output escaping is to be disabled
+ * when writing to a final result tree that is not being serialized.
+ * Action: The optional recovery action is to ignore the disable-output-escaping
+ * attribute.
+ */
+ XTRE1630,
+
+ /**
+ * A basic XSLT processor must raise a non-recoverable dynamic error
+ * if the input to the processor includes a node with a type annotation
+ * other than xs:untyped or xs:untypedAtomic, or an atomic value
+ * of a type other than those which a basic XSLT processor supports.
+ */
+ XTDE1665
+
+ };
+
+ /**
+ * Issues a warning, should not be used excessively. This can
+ * be used to communicate that a certain implementation defined
+ * feature is unsupported or that a certain expression most likely
+ * doesn't do what the users wants, to name a few examples.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#errors">XML Path Language (XPath) 2.0,
+ * 2.3 Error Handling</a>
+ * @param message the message to be read by the user.
+ * @param sourceLocation the location of where the warning originates from.
+ */
+ void warning(const QString &message, const QSourceLocation &sourceLocation = QSourceLocation());
+
+ /**
+ * Issues an error. May be used at the static analysis phase or
+ * the dynamic evaluation phase.
+ *
+ * For SourceLocationReflection instances, the overload taking an SouourceLocationReflection should be used.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#errors">XML Path Language (XPath) 2.0,
+ * 2.3 Error Handling</a>
+ * @param message the message to be read by the user.
+ * @param errorCode identifies the error condition, as described
+ * @param sourceLocation the location of where the error originates from
+ * in "XML Path Language (XPath) 2.0" section "G Error Conditions"
+ */
+ void error(const QString &message,
+ const ReportContext::ErrorCode errorCode,
+ const QSourceLocation &sourceLocation);
+
+ /**
+ * Overload.
+ *
+ * Same as the above, but passes the SourceLocationReflection as reference for error reporting.
+ */
+ void error(const QString &message,
+ const ReportContext::ErrorCode errorCode,
+ const SourceLocationReflection *const reflection);
+
+ /**
+ * Issues an error which is not identified in the XPath specifications. This function
+ * is among other things used for implementing the <tt>fn:error()</tt> function.
+ */
+ void error(const QString &message,
+ const QXmlName qName,
+ const SourceLocationReflection *const r);
+
+ /**
+ * @return the QAbstractMessageHandler which functions such as warning() and
+ * error() should submit messages to. This function
+ * may never return @c null; a valid QAbstractMessageHandler pointer must always be returned.
+ */
+ virtual QAbstractMessageHandler *messageHandler() const = 0;
+
+ virtual NamePool::Ptr namePool() const = 0;
+
+ /**
+ * Returns a string representation of the error code @p code.
+ *
+ * @see ReportContext::ErrorCode
+ * @param errorCode identifies the error condition, as described
+ * in <a href="http://www.w3.org/TR/xpath20/#id-errors">XML Path
+ * Language (XPath) 2.0, G Error Conditions</a>
+ */
+ static QString codeToString(const ReportContext::ErrorCode errorCode);
+
+ /**
+ * @returns the error code part of @p typeURI and sets @p uri to the error namespace. Note
+ * that the error namespace not necessarily is the namespace for XPath and
+ * XQuery errors, http://www.w3.org/2005/xqt-errors, but can be user defined.
+ */
+ static QString codeFromURI(const QString &typeURI,
+ QString &uri);
+
+ /**
+ * @short Returns the source location applying for @p reflection.
+ */
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const = 0;
+
+ /**
+ * Resolves @p relative against @p baseURI, possibly using a URI resolver.
+ */
+ QUrl resolveURI(const QUrl &relative,
+ const QUrl &baseURI) const;
+
+ /**
+ * @short The URI resolver in use.
+ *
+ * If no URI resolver is in use, a @c null pointer is returned.
+ *
+ * @note You should probably use resolveURI(), which handles the case of
+ * when uriResolver() is @c null.
+ */
+ virtual const QAbstractUriResolver *uriResolver() const = 0;
+
+ private:
+ void createError(const QString &description,
+ const QtMsgType type,
+ const QUrl &id,
+ const QSourceLocation &sourceLocation) const;
+ static inline QString finalizeDescription(const QString &desc);
+ QSourceLocation lookupSourceLocation(const SourceLocationReflection *const ref) const;
+
+ Q_DISABLE_COPY(ReportContext)
+ };
+
+ /**
+ * @short This is the class type that is being thrown when a query error occur.
+ *
+ * @relates ReportContext
+ */
+ typedef bool Exception;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qstackcontextbase.cpp b/src/xmlpatterns/environment/qstackcontextbase.cpp
new file mode 100644
index 0000000..cd22a55
--- /dev/null
+++ b/src/xmlpatterns/environment/qstackcontextbase.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qstackcontextbase_p.h.
+ * If you need includes in this file, put them in qstackcontextbase_p.h, outside of the namespace.
+ */
+
+template<typename TSuperClass>
+StackContextBase<TSuperClass>::StackContextBase() : m_rangeVariables(10),
+ m_expressionVariables(10),
+ m_positionIterators(5),
+ m_itemCacheCells(5),
+ m_itemSequenceCacheCells(5)
+{
+ /* The m_* containers are initialized with default sizes. Estimated guesses on usage patterns. */
+}
+
+template<typename TSuperClass>
+StackContextBase<TSuperClass>::StackContextBase(const DynamicContext::Ptr &prevContext)
+ : TSuperClass(prevContext),
+ m_rangeVariables(10),
+ m_expressionVariables(10),
+ m_positionIterators(5),
+ m_itemCacheCells(5),
+ m_itemSequenceCacheCells(5)
+{
+ Q_ASSERT(prevContext);
+}
+
+template<typename TSuperClass>
+ItemCacheCell &StackContextBase<TSuperClass>::itemCacheCell(const VariableSlotID slot)
+{
+ if(slot >= m_itemCacheCells.size())
+ m_itemCacheCells.resize(qMax(slot + 1, m_itemCacheCells.size()));
+
+ return m_itemCacheCells[slot];
+}
+
+template<typename TSuperClass>
+ItemSequenceCacheCell::Vector &StackContextBase<TSuperClass>::itemSequenceCacheCells(const VariableSlotID slot)
+{
+ if(slot >= m_itemSequenceCacheCells.size())
+ m_itemSequenceCacheCells.resize(qMax(slot + 1, m_itemSequenceCacheCells.size()));
+
+ return m_itemSequenceCacheCells;
+}
+
+template<typename TSuperClass>
+Item StackContextBase<TSuperClass>::rangeVariable(const VariableSlotID slot) const
+{
+ Q_ASSERT(slot < m_rangeVariables.size());
+ Q_ASSERT(m_rangeVariables.at(slot));
+ return m_rangeVariables.at(slot);
+}
+
+template<typename TSuperClass>
+Expression::Ptr StackContextBase<TSuperClass>::expressionVariable(const VariableSlotID slot) const
+{
+ Q_ASSERT(slot < m_expressionVariables.size());
+ Q_ASSERT(m_expressionVariables.at(slot));
+ return m_expressionVariables.at(slot);
+}
+
+template<typename TSuperClass>
+Item::Iterator::Ptr StackContextBase<TSuperClass>::positionIterator(const VariableSlotID slot) const
+{
+ Q_ASSERT(slot < m_positionIterators.size());
+ return m_positionIterators.at(slot);
+}
+
+template<typename TSuperClass>
+template<typename VectorType, typename UnitType>
+inline
+void StackContextBase<TSuperClass>::setSlotVariable(const VariableSlotID slot,
+ const UnitType &newValue,
+ VectorType &container) const
+{
+ if(slot < container.size())
+ container.replace(slot, newValue);
+ else
+ {
+ container.resize(slot + 1);
+ container.replace(slot, newValue);
+ }
+}
+
+template<typename TSuperClass>
+void StackContextBase<TSuperClass>::setRangeVariable(const VariableSlotID slot,
+ const Item &newValue)
+{
+ setSlotVariable(slot, newValue, m_rangeVariables);
+}
+
+template<typename TSuperClass>
+void StackContextBase<TSuperClass>::setExpressionVariable(const VariableSlotID slot,
+ const Expression::Ptr &newValue)
+{
+ setSlotVariable(slot, newValue, m_expressionVariables);
+}
+
+template<typename TSuperClass>
+void StackContextBase<TSuperClass>::setPositionIterator(const VariableSlotID slot,
+ const Item::Iterator::Ptr &newValue)
+{
+ setSlotVariable(slot, newValue, m_positionIterators);
+}
+
+template<typename TSuperClass>
+DynamicContext::TemplateParameterHash &StackContextBase<TSuperClass>::templateParameterStore()
+{
+ return m_templateParameterStore;
+}
+
diff --git a/src/xmlpatterns/environment/qstackcontextbase_p.h b/src/xmlpatterns/environment/qstackcontextbase_p.h
new file mode 100644
index 0000000..9a2d3cf
--- /dev/null
+++ b/src/xmlpatterns/environment/qstackcontextbase_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StackContextBase_H
+#define Patternist_StackContextBase_H
+
+#include <QVector>
+
+#include "qdaytimeduration_p.h"
+#include "qdelegatingdynamiccontext_p.h"
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all DynamicContext classes that needs to supply
+ * variables. It has a new frame for local caches, position iterators,
+ * expressions, range variables, template parameters but notably continues
+ * to delegate global caches.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<typename TSuperClass>
+ class StackContextBase : public TSuperClass
+ {
+ public:
+ StackContextBase();
+ /**
+ * Construct a StackContextBase and passes @p prevContext to its super class. This
+ * constructor is typically used when the super class is DelegatingDynamicContext.
+ */
+ StackContextBase(const DynamicContext::Ptr &prevContext);
+
+ virtual void setRangeVariable(const VariableSlotID slotNumber,
+ const Item &newValue);
+ virtual Item rangeVariable(const VariableSlotID slotNumber) const;
+
+ virtual void setExpressionVariable(const VariableSlotID slotNumber,
+ const Expression::Ptr &newValue);
+ virtual Expression::Ptr expressionVariable(const VariableSlotID slotNumber) const;
+
+ virtual Item::Iterator::Ptr positionIterator(const VariableSlotID slot) const;
+ virtual void setPositionIterator(const VariableSlotID slot,
+ const Item::Iterator::Ptr &newValue);
+ virtual ItemCacheCell &itemCacheCell(const VariableSlotID slot);
+ virtual ItemSequenceCacheCell::Vector &itemSequenceCacheCells(const VariableSlotID slot);
+
+ virtual DynamicContext::TemplateParameterHash &templateParameterStore();
+
+ protected:
+ /**
+ * This function is protected, although it only is used in this class. I don't
+ * know why it has to be, but it won't compile when private.
+ */
+ template<typename VectorType, typename UnitType>
+ inline
+ void setSlotVariable(const VariableSlotID slot,
+ const UnitType &newValue,
+ VectorType &container) const;
+
+ private:
+ Item::Vector m_rangeVariables;
+ Expression::Vector m_expressionVariables;
+ Item::Iterator::Vector m_positionIterators;
+ ItemCacheCell::Vector m_itemCacheCells;
+ ItemSequenceCacheCell::Vector m_itemSequenceCacheCells;
+ DynamicContext::TemplateParameterHash m_templateParameterStore;
+ };
+
+ #include "qstackcontextbase.cpp"
+
+ /**
+ * @short A DynamicContext that creates a new scope for variables.
+ *
+ * This DynamicContext is used for recursive user function calls, for example.
+ */
+ typedef StackContextBase<DelegatingDynamicContext> StackContext;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qstaticbaseuricontext.cpp b/src/xmlpatterns/environment/qstaticbaseuricontext.cpp
new file mode 100644
index 0000000..6907078
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticbaseuricontext.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstaticbaseuricontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticBaseURIContext::StaticBaseURIContext(const QUrl &bURI,
+ const StaticContext::Ptr &prevContext) : DelegatingStaticContext(prevContext)
+ , m_baseURI(bURI)
+{
+ Q_ASSERT(m_baseURI.isValid());
+ Q_ASSERT(!m_baseURI.isRelative());
+ Q_ASSERT(prevContext);
+}
+
+QUrl StaticBaseURIContext::baseURI() const
+{
+ return m_baseURI;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qstaticbaseuricontext_p.h b/src/xmlpatterns/environment/qstaticbaseuricontext_p.h
new file mode 100644
index 0000000..555b560
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticbaseuricontext_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticBaseURIContext_H
+#define Patternist_StaticBaseURIContext_H
+
+#include "qdelegatingstaticcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A StaticContext that changes the static base URI.
+ * of items.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StaticBaseURIContext : public DelegatingStaticContext
+ {
+ public:
+ /**
+ * The @p bURI is the new static base URI, and it must be valid
+ * and absolute.
+ */
+ StaticBaseURIContext(const QUrl &bURI,
+ const StaticContext::Ptr &prevContext);
+
+ virtual QUrl baseURI() const;
+
+ private:
+ const QUrl m_baseURI;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp b/src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp
new file mode 100644
index 0000000..be86573
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstaticcompatibilitycontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticCompatibilityContext::StaticCompatibilityContext(const StaticContext::Ptr &context) : DelegatingStaticContext(context)
+{
+}
+
+bool StaticCompatibilityContext::compatModeEnabled() const
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h b/src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h
new file mode 100644
index 0000000..dbec0e9
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticCompatibilityContext_H
+#define Patternist_StaticCompatibilityContext_H
+
+#include "qdelegatingstaticcontext_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Has the XPath Compatibility Mode activated. Used for XSL-T 2.0's
+ * compatibility mode.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT StaticCompatibilityContext : public DelegatingStaticContext
+ {
+ public:
+ StaticCompatibilityContext(const StaticContext::Ptr &context);
+
+ /**
+ * Returns always @c true.
+ */
+ virtual bool compatModeEnabled() const;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qstaticcontext.cpp b/src/xmlpatterns/environment/qstaticcontext.cpp
new file mode 100644
index 0000000..0c2f097
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcontext.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonnamespaces_p.h"
+#include "qexpression_p.h"
+
+#include "qstaticcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticContext::~StaticContext()
+{
+}
+
+void StaticContext::wrapExpressionWith(const SourceLocationReflection *const existingNode,
+ const QExplicitlySharedDataPointer<Expression> &newNode)
+{
+ addLocation(newNode.data(), locationFor(existingNode));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qstaticcontext_p.h b/src/xmlpatterns/environment/qstaticcontext_p.h
new file mode 100644
index 0000000..ed45987
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcontext_p.h
@@ -0,0 +1,299 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticContext_H
+#define Patternist_StaticContext_H
+
+#include "qexternalvariableloader_p.h"
+#include "qitemtype_p.h"
+#include "qnamepool_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qreportcontext_p.h"
+#include "qresourceloader_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QUrl;
+template<typename Key, typename T> class QHash;
+
+namespace QPatternist
+{
+ class DynamicContext;
+ class Expression;
+ class FunctionFactory;
+ class SchemaTypeFactory;
+
+ /**
+ * @short Carries information and facilities used at compilation time.
+ *
+ * A representation of the Static Context in XPath 2.0. The Static Context
+ * contains information which doesn't change and is the "outer scope" of the
+ * expression. It provides for example a base URI the expression can relate to and
+ * what functions and variables that are available for the expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#static_context">XML Path
+ * Language (XPath) 2.0, 2.1.1 Static Context</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StaticContext : public ReportContext
+ {
+ public:
+ /**
+ * A smart pointer wrapping StaticContext instances.
+ */
+ typedef QExplicitlySharedDataPointer<StaticContext> Ptr;
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xquery/#id-boundary-space-decls">XQuery 1.0:
+ * An XML Query Language, 4.3 Boundary-space Declaration</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#dt-boundary-space-policy">XQuery 1.0:
+ * An XML Query Language, Definition: Boundary-space policy</a>
+ */
+ enum BoundarySpacePolicy
+ {
+ BSPPreserve,
+ BSPStrip
+ };
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xquery/#id-construction-declaration">XQuery 1.0:
+ * An XML Query Language, 4.6 Construction Declaration</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#dt-construction-mode">XQuery 1.0:
+ * An XML Query Language, Definition: Construction mode</a>
+ */
+ enum ConstructionMode
+ {
+ CMPreserve,
+ CMStrip
+ };
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xquery/#id-default-ordering-decl">XQuery 1.0:
+ * An XML Query Language, 4.7 Ordering Mode Declaration</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#dt-ordering-mode">XQuery 1.0:
+ * An XML Query Language, Definition: Ordering mode</a>
+ */
+ enum OrderingMode
+ {
+ Ordered,
+ Unordered
+ };
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xquery/#id-empty-order-decl">XQuery 1.0:
+ * An XML Query Language, 4.8 Empty Order Declaration</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#dt-default-empty-order">XQuery 1.0:
+ * An XML Query Language, Definition: Default order for empty sequences</a>
+ */
+ enum OrderingEmptySequence
+ {
+ Greatest,
+ Least
+ };
+
+ enum InheritMode
+ {
+ Inherit,
+ NoInherit
+ };
+
+ enum PreserveMode
+ {
+ Preserve,
+ NoPreserve
+ };
+
+ inline StaticContext()
+ {
+ }
+
+ virtual ~StaticContext();
+
+ virtual NamespaceResolver::Ptr namespaceBindings() const = 0;
+ virtual void setNamespaceBindings(const NamespaceResolver::Ptr &) = 0;
+ virtual QExplicitlySharedDataPointer<FunctionFactory> functionSignatures() const = 0;
+ virtual QExplicitlySharedDataPointer<SchemaTypeFactory> schemaDefinitions() const = 0;
+
+ /**
+ * The base URI of the context. Typically, this is the base URI
+ * if of the element that contained the expression.
+ *
+ * The base URI is in this implementation is never undefined, but is
+ * always valid.
+ */
+ virtual QUrl baseURI() const = 0;
+
+ virtual void setBaseURI(const QUrl &uri) = 0;
+
+ /**
+ * @returns always the standard function namespace defined in
+ * <a href="http://www.w3.org/TR/xpath-functions/">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators</a>
+ */
+ virtual QString defaultFunctionNamespace() const = 0;
+ virtual void setDefaultFunctionNamespace(const QString &ns) = 0;
+
+ virtual QString defaultElementNamespace() const = 0;
+ virtual void setDefaultElementNamespace(const QString &ns) = 0;
+
+ /**
+ * @returns the URI identifying the default collation. The function
+ * is responsible for ensuring a collation is always returned. If
+ * a collation is not provided by the user or the host language in the
+ * context, the Unicode codepoint URI should be returned.
+ */
+ virtual QUrl defaultCollation() const = 0;
+
+ virtual void setDefaultCollation(const QUrl &uri) = 0;
+
+ /**
+ * Determine whether Backwards Compatible Mode is used.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-backwards-compatibility">XML Path
+ * Language (XPath) 2.0, I Backwards Compatibility with XPath 1.0 (Non-Normative)</a>
+ * @see <a href="http://www.w3.org/TR/xpath20/#dt-xpath-compat-mode">XML Path
+ * Language (XPath) 2.0, Definition: XPath 1.0 compatibility mode</a>
+ */
+ virtual bool compatModeEnabled() const = 0;
+
+ virtual void setCompatModeEnabled(const bool newVal) = 0;
+
+ /**
+ * This is the DynamicContext that is used for pre-evaluation at
+ * compilation time, const-folding at the static stage.
+ */
+ virtual QExplicitlySharedDataPointer<DynamicContext> dynamicContext() const = 0;
+
+ virtual BoundarySpacePolicy boundarySpacePolicy() const = 0;
+ virtual void setBoundarySpacePolicy(const BoundarySpacePolicy policy) = 0;
+
+ virtual ConstructionMode constructionMode() const = 0;
+ virtual void setConstructionMode(const ConstructionMode mode) = 0;
+
+ virtual OrderingMode orderingMode() const = 0;
+ virtual void setOrderingMode(const OrderingMode mode) = 0;
+ virtual OrderingEmptySequence orderingEmptySequence() const = 0;
+ virtual void setOrderingEmptySequence(const OrderingEmptySequence ordering) = 0;
+
+ virtual InheritMode inheritMode() const = 0;
+ virtual void setInheritMode(const InheritMode mode) = 0;
+
+ virtual PreserveMode preserveMode() const = 0;
+ virtual void setPreserveMode(const PreserveMode mode) = 0;
+
+ /**
+ * @short The static type of the context item.
+ *
+ * Different StaticContext instances are used for different nodes in the
+ * AST to properly reflect the type of the focus. If the focus is undefined,
+ * this function must return @c null.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#dt-context-item-static-type">XQuery
+ * 1.0: An XML Query Language, Definition: Context item static type</a>
+ */
+ virtual ItemType::Ptr contextItemType() const = 0;
+
+ /**
+ * @short The static type of the current item, as returned by @c
+ * fn:current().
+ */
+ virtual ItemType::Ptr currentItemType() const = 0;
+
+ /**
+ * Copies this StaticContext and returns the copy.
+ *
+ * The copy and original must not be independent. Since the StaticContext is modified
+ * during the compilation process, the copy must be independent from the original
+ * to the degree that is required for the subclass in question.
+ */
+ virtual StaticContext::Ptr copy() const = 0;
+
+ virtual ExternalVariableLoader::Ptr externalVariableLoader() const = 0;
+ virtual ResourceLoader::Ptr resourceLoader() const = 0;
+ virtual NamePool::Ptr namePool() const = 0;
+
+ /**
+ * @short Adds @p location for @p reflection.
+ */
+ virtual void addLocation(const SourceLocationReflection *const reflection,
+ const QSourceLocation &location) = 0;
+
+ /**
+ * @short Returns a hash of the contained locations.
+ *
+ * The key is the address for the expression, and the value is its location. Note
+ * that the key cannot be dereferenced, there's no guarantee the
+ * Expression is in scope. The key is merely an identifier.
+ */
+ virtual LocationHash sourceLocations() const = 0;
+
+ virtual VariableSlotID currentRangeSlot() const = 0;
+ virtual VariableSlotID allocateRangeSlot() = 0;
+
+ /**
+ * @short Ensures source locations are handled in such a manner that @p
+ * existingNode wraps @p newNode.
+ *
+ * Ensures that the source locations for @p existingNode, applies to
+ * @p newNode.
+ */
+ void wrapExpressionWith(const SourceLocationReflection *const existingNode,
+ const QExplicitlySharedDataPointer<Expression> &newNode);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qstaticcurrentcontext.cpp b/src/xmlpatterns/environment/qstaticcurrentcontext.cpp
new file mode 100644
index 0000000..421eb78
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcurrentcontext.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstaticcurrentcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticCurrentContext::StaticCurrentContext(const ItemType::Ptr &t,
+ const StaticContext::Ptr &context) : DelegatingStaticContext(context)
+ , m_currentItemType(t)
+{
+ Q_ASSERT(m_currentItemType);
+}
+
+ItemType::Ptr StaticCurrentContext::currentItemType() const
+{
+ return m_currentItemType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qstaticcurrentcontext_p.h b/src/xmlpatterns/environment/qstaticcurrentcontext_p.h
new file mode 100644
index 0000000..49e7523
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcurrentcontext_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticCurrentContext_H
+#define Patternist_StaticCurrentContext_H
+
+#include "qdelegatingstaticcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A StaticContext that carries a specified static type for the
+ * current item, as returned by @c fn:current(), but otherwise delegates to
+ * another StaticContext.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT StaticCurrentContext : public DelegatingStaticContext
+ {
+ public:
+ StaticCurrentContext(const ItemType::Ptr &currentItemType,
+ const StaticContext::Ptr &context);
+ /**
+ * @returns the type passed in the constructor.
+ */
+ virtual ItemType::Ptr currentItemType() const;
+
+ private:
+ const ItemType::Ptr m_currentItemType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qstaticfocuscontext.cpp b/src/xmlpatterns/environment/qstaticfocuscontext.cpp
new file mode 100644
index 0000000..3c21f69
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticfocuscontext.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstaticfocuscontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticFocusContext::StaticFocusContext(const ItemType::Ptr &t,
+ const StaticContext::Ptr &context) : DelegatingStaticContext(context)
+ , m_contextItemType(t)
+{
+}
+
+ItemType::Ptr StaticFocusContext::contextItemType() const
+{
+ return m_contextItemType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qstaticfocuscontext_p.h b/src/xmlpatterns/environment/qstaticfocuscontext_p.h
new file mode 100644
index 0000000..53308d0
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticfocuscontext_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticFocusContext_H
+#define Patternist_StaticFocusContext_H
+
+#include "qdelegatingstaticcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A StaticContext that carries a specified static type
+ * for the context item, but otherwise delegates to another StaticContext.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT StaticFocusContext : public DelegatingStaticContext
+ {
+ public:
+ /**
+ * @p contextItemType may be @c null.
+ */
+ StaticFocusContext(const ItemType::Ptr &contextItemType,
+ const StaticContext::Ptr &context);
+ /**
+ * @returns the type passed in the constructor.
+ */
+ virtual ItemType::Ptr contextItemType() const;
+
+ private:
+ const ItemType::Ptr m_contextItemType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/environment/qstaticnamespacecontext.cpp b/src/xmlpatterns/environment/qstaticnamespacecontext.cpp
new file mode 100644
index 0000000..521d504
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticnamespacecontext.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstaticnamespacecontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticNamespaceContext::StaticNamespaceContext(const NamespaceResolver::Ptr &resolver,
+ const StaticContext::Ptr &context) : DelegatingStaticContext(context)
+ , m_namespaceBindings(resolver)
+{
+ Q_ASSERT(m_namespaceBindings);
+}
+
+NamespaceResolver::Ptr StaticNamespaceContext::namespaceBindings() const
+{
+ return m_namespaceBindings;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/environment/qstaticnamespacecontext_p.h b/src/xmlpatterns/environment/qstaticnamespacecontext_p.h
new file mode 100644
index 0000000..3aa1487
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticnamespacecontext_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticNamespaceContext_H
+#define Patternist_StaticNamespaceContext_H
+
+#include "qdelegatingstaticcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A StaticContext that carries a specified namespace resolver
+ * for the context item, but otherwise delegates to another StaticContext.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT StaticNamespaceContext : public DelegatingStaticContext
+ {
+ public:
+ StaticNamespaceContext(const NamespaceResolver::Ptr &resolver,
+ const StaticContext::Ptr &context);
+
+ /**
+ * @returns the resolver passed in the constructor.
+ */
+ virtual NamespaceResolver::Ptr namespaceBindings() const;
+
+ private:
+ const NamespaceResolver::Ptr m_namespaceBindings;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/expr.pri b/src/xmlpatterns/expr/expr.pri
new file mode 100644
index 0000000..81c3994
--- /dev/null
+++ b/src/xmlpatterns/expr/expr.pri
@@ -0,0 +1,173 @@
+HEADERS += $$PWD/qandexpression_p.h \
+ $$PWD/qapplytemplate_p.h \
+ $$PWD/qargumentreference_p.h \
+ $$PWD/qarithmeticexpression_p.h \
+ $$PWD/qattributeconstructor_p.h \
+ $$PWD/qattributenamevalidator_p.h \
+ $$PWD/qaxisstep_p.h \
+ $$PWD/qcachecells_p.h \
+ $$PWD/qcallsite_p.h \
+ $$PWD/qcalltargetdescription_p.h \
+ $$PWD/qcalltemplate_p.h \
+ $$PWD/qcastableas_p.h \
+ $$PWD/qcastas_p.h \
+ $$PWD/qcastingplatform_p.h \
+ $$PWD/qcollationchecker_p.h \
+ $$PWD/qcombinenodes_p.h \
+ $$PWD/qcommentconstructor_p.h \
+ $$PWD/qcomparisonplatform_p.h \
+ $$PWD/qcomputednamespaceconstructor_p.h \
+ $$PWD/qcontextitem_p.h \
+ $$PWD/qcopyof_p.h \
+ $$PWD/qcurrentitemstore_p.h \
+ $$PWD/qdocumentconstructor_p.h \
+ $$PWD/qdocumentcontentvalidator_p.h \
+ $$PWD/qdynamiccontextstore_p.h \
+ $$PWD/qelementconstructor_p.h \
+ $$PWD/qemptycontainer_p.h \
+ $$PWD/qemptysequence_p.h \
+ $$PWD/qevaluationcache_p.h \
+ $$PWD/qexpressiondispatch_p.h \
+ $$PWD/qexpressionfactory_p.h \
+ $$PWD/qexpression_p.h \
+ $$PWD/qexpressionsequence_p.h \
+ $$PWD/qexpressionvariablereference_p.h \
+ $$PWD/qexternalvariableloader_p.h \
+ $$PWD/qexternalvariablereference_p.h \
+ $$PWD/qfirstitempredicate_p.h \
+ $$PWD/qforclause_p.h \
+ $$PWD/qgeneralcomparison_p.h \
+ $$PWD/qgenericpredicate_p.h \
+ $$PWD/qifthenclause_p.h \
+ $$PWD/qinstanceof_p.h \
+ $$PWD/qletclause_p.h \
+ $$PWD/qliteral_p.h \
+ $$PWD/qliteralsequence_p.h \
+ $$PWD/qnamespaceconstructor_p.h \
+ $$PWD/qncnameconstructor_p.h \
+ $$PWD/qnodecomparison_p.h \
+ $$PWD/qnodesort_p.h \
+ $$PWD/qoperandsiterator_p.h \
+ $$PWD/qoptimizationpasses_p.h \
+ $$PWD/qoptimizerblocks_p.h \
+ $$PWD/qoptimizerframework_p.h \
+ $$PWD/qorderby_p.h \
+ $$PWD/qorexpression_p.h \
+ $$PWD/qpaircontainer_p.h \
+ $$PWD/qparentnodeaxis_p.h \
+ $$PWD/qpath_p.h \
+ $$PWD/qpositionalvariablereference_p.h \
+ $$PWD/qprocessinginstructionconstructor_p.h \
+ $$PWD/qqnameconstructor_p.h \
+ $$PWD/qquantifiedexpression_p.h \
+ $$PWD/qrangeexpression_p.h \
+ $$PWD/qrangevariablereference_p.h \
+ $$PWD/qreturnorderby_p.h \
+ $$PWD/qsimplecontentconstructor_p.h \
+ $$PWD/qsinglecontainer_p.h \
+ $$PWD/qsourcelocationreflection_p.h \
+ $$PWD/qstaticbaseuristore_p.h \
+ $$PWD/qstaticcompatibilitystore_p.h \
+ $$PWD/qtemplatemode_p.h \
+ $$PWD/qtemplateparameterreference_p.h \
+ $$PWD/qtemplatepattern_p.h \
+ $$PWD/qtemplatepattern_p.h \
+ $$PWD/qtemplate_p.h \
+ $$PWD/qtextnodeconstructor_p.h \
+ $$PWD/qtreatas_p.h \
+ $$PWD/qtriplecontainer_p.h \
+ $$PWD/qtruthpredicate_p.h \
+ $$PWD/qunaryexpression_p.h \
+ $$PWD/qunlimitedcontainer_p.h \
+ $$PWD/qunresolvedvariablereference_p.h \
+ $$PWD/quserfunctioncallsite_p.h \
+ $$PWD/quserfunction_p.h \
+ $$PWD/qvalidate_p.h \
+ $$PWD/qvaluecomparison_p.h \
+ $$PWD/qvariabledeclaration_p.h \
+ $$PWD/qvariablereference_p.h \
+ $$PWD/qwithparam_p.h \
+ $$PWD/qxsltsimplecontentconstructor_p.h
+
+SOURCES += $$PWD/qandexpression.cpp \
+ $$PWD/qapplytemplate.cpp \
+ $$PWD/qargumentreference.cpp \
+ $$PWD/qarithmeticexpression.cpp \
+ $$PWD/qattributeconstructor.cpp \
+ $$PWD/qattributenamevalidator.cpp \
+ $$PWD/qaxisstep.cpp \
+ $$PWD/qcallsite.cpp \
+ $$PWD/qcalltargetdescription.cpp \
+ $$PWD/qcalltemplate.cpp \
+ $$PWD/qcastableas.cpp \
+ $$PWD/qcastas.cpp \
+ $$PWD/qcollationchecker.cpp \
+ $$PWD/qcombinenodes.cpp \
+ $$PWD/qcommentconstructor.cpp \
+ $$PWD/qcomputednamespaceconstructor.cpp \
+ $$PWD/qcontextitem.cpp \
+ $$PWD/qcopyof.cpp \
+ $$PWD/qcurrentitemstore.cpp \
+ $$PWD/qdocumentconstructor.cpp \
+ $$PWD/qdocumentcontentvalidator.cpp \
+ $$PWD/qdynamiccontextstore.cpp \
+ $$PWD/qelementconstructor.cpp \
+ $$PWD/qemptycontainer.cpp \
+ $$PWD/qemptysequence.cpp \
+ $$PWD/qexpression.cpp \
+ $$PWD/qexpressionfactory.cpp \
+ $$PWD/qexpressionsequence.cpp \
+ $$PWD/qexpressionvariablereference.cpp \
+ $$PWD/qexternalvariableloader.cpp \
+ $$PWD/qexternalvariablereference.cpp \
+ $$PWD/qfirstitempredicate.cpp \
+ $$PWD/qforclause.cpp \
+ $$PWD/qgeneralcomparison.cpp \
+ $$PWD/qgenericpredicate.cpp \
+ $$PWD/qifthenclause.cpp \
+ $$PWD/qinstanceof.cpp \
+ $$PWD/qletclause.cpp \
+ $$PWD/qliteral.cpp \
+ $$PWD/qliteralsequence.cpp \
+ $$PWD/qnamespaceconstructor.cpp \
+ $$PWD/qncnameconstructor.cpp \
+ $$PWD/qnodecomparison.cpp \
+ $$PWD/qnodesort.cpp \
+ $$PWD/qoptimizationpasses.cpp \
+ $$PWD/qoptimizerblocks.cpp \
+ $$PWD/qoptimizerframework.cpp \
+ $$PWD/qorderby.cpp \
+ $$PWD/qorexpression.cpp \
+ $$PWD/qpaircontainer.cpp \
+ $$PWD/qparentnodeaxis.cpp \
+ $$PWD/qpath.cpp \
+ $$PWD/qpositionalvariablereference.cpp \
+ $$PWD/qprocessinginstructionconstructor.cpp \
+ $$PWD/qqnameconstructor.cpp \
+ $$PWD/qquantifiedexpression.cpp \
+ $$PWD/qrangeexpression.cpp \
+ $$PWD/qrangevariablereference.cpp \
+ $$PWD/qreturnorderby.cpp \
+ $$PWD/qsimplecontentconstructor.cpp \
+ $$PWD/qsinglecontainer.cpp \
+ $$PWD/qsourcelocationreflection.cpp \
+ $$PWD/qstaticbaseuristore.cpp \
+ $$PWD/qstaticcompatibilitystore.cpp \
+ $$PWD/qtemplate.cpp \
+ $$PWD/qtemplateinvoker.cpp \
+ $$PWD/qtemplatemode.cpp \
+ $$PWD/qtemplateparameterreference.cpp \
+ $$PWD/qtextnodeconstructor.cpp \
+ $$PWD/qtreatas.cpp \
+ $$PWD/qtriplecontainer.cpp \
+ $$PWD/qtruthpredicate.cpp \
+ $$PWD/qunaryexpression.cpp \
+ $$PWD/qunlimitedcontainer.cpp \
+ $$PWD/qunresolvedvariablereference.cpp \
+ $$PWD/quserfunctioncallsite.cpp \
+ $$PWD/quserfunction.cpp \
+ $$PWD/qvalidate.cpp \
+ $$PWD/qvaluecomparison.cpp \
+ $$PWD/qvariabledeclaration.cpp \
+ $$PWD/qvariablereference.cpp \
+ $$PWD/qxsltsimplecontentconstructor.cpp
diff --git a/src/xmlpatterns/expr/qandexpression.cpp b/src/xmlpatterns/expr/qandexpression.cpp
new file mode 100644
index 0000000..ae1d6f2
--- /dev/null
+++ b/src/xmlpatterns/expr/qandexpression.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qandexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AndExpression::AndExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : PairContainer(operand1, operand2)
+{
+}
+
+bool AndExpression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context) && m_operand2->evaluateEBV(context);
+}
+
+Expression::Ptr AndExpression::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr newMe(PairContainer::compress(context));
+
+ if(newMe != this)
+ return newMe;
+
+ /* Both operands mustn't be evaluated in order to be able to compress. */
+ if(m_operand1->isEvaluated() && !m_operand1->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ else if(m_operand2->isEvaluated() && !m_operand2->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ else
+ return Expression::Ptr(this);
+}
+
+SequenceType::List AndExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::EBV);
+ result.append(CommonSequenceTypes::EBV);
+ return result;
+}
+
+SequenceType::Ptr AndExpression::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr AndExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qandexpression_p.h b/src/xmlpatterns/expr/qandexpression_p.h
new file mode 100644
index 0000000..b4fd87c
--- /dev/null
+++ b/src/xmlpatterns/expr/qandexpression_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AndExpression_H
+#define Patternist_AndExpression_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's logical expression @c and.
+ *
+ * The @c and expression is the same in XQuery 1.0 as in XPath 2.0.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-logical-expressions">XML Path Language
+ * (XPath) 2.0, 3.6 Logical Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class AndExpression : public PairContainer
+ {
+ public:
+ AndExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneBoolean
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qapplytemplate.cpp b/src/xmlpatterns/expr/qapplytemplate.cpp
new file mode 100644
index 0000000..2a9f501
--- /dev/null
+++ b/src/xmlpatterns/expr/qapplytemplate.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDebug>
+
+#include "qaxisstep_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qsequencemappingiterator_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qapplytemplate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ApplyTemplate::ApplyTemplate(const TemplateMode::Ptr &mode,
+ const WithParam::Hash &withParams,
+ const TemplateMode::Ptr &defaultMode) : TemplateInvoker(withParams)
+ , m_mode(mode)
+ , m_defaultMode(defaultMode)
+{
+ Q_ASSERT_X(m_mode || m_defaultMode, Q_FUNC_INFO,
+ "Either a mode, or the default mode must be supplied.");
+}
+
+Item ApplyTemplate::mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &) const
+{
+ return Item(node);
+}
+
+Item::Iterator::Ptr ApplyTemplate::mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ Q_UNUSED(item);
+ return evaluateSequence(context);
+}
+
+TemplateMode::Ptr ApplyTemplate::effectiveMode(const DynamicContext::Ptr &context) const
+{
+ if(m_mode)
+ return m_mode;
+ else
+ {
+ const TemplateMode::Ptr currentMode(context->currentTemplateMode());
+
+ if(currentMode)
+ return currentMode;
+ else
+ return m_defaultMode;
+ }
+}
+
+Template::Ptr ApplyTemplate::findTemplate(const DynamicContext::Ptr &context,
+ const TemplateMode::Ptr &templateMode) const
+{
+ const int count = templateMode->templatePatterns.count();
+ Template::Ptr result;
+ /* It's redundant to initialize these values, but it suppresses false
+ * positives with GCC. */
+ PatternPriority priority = 0;
+ TemplatePattern::ID id = -1;
+
+ /* Possible optimization: detecting ambiguous rule matches could be forked off to a
+ * low prioirity thread. */
+ for(int i = 0; i < count; ++i)
+ {
+ const TemplatePattern::Ptr &candidate = templateMode->templatePatterns.at(i);
+ if(candidate->matchPattern()->evaluateEBV(context))
+ {
+ if(result)
+ {
+ if( candidate->id() != id
+ && candidate->priority() == priority
+ && candidate->templateTarget()->importPrecedence ==
+ result->importPrecedence)
+ {
+ context->error(QtXmlPatterns::tr("Ambiguous rule match."),
+ ReportContext::XTRE0540, this);
+ }
+ else
+ break;
+ }
+ else
+ {
+ result = candidate->templateTarget();
+ priority = candidate->priority();
+ id = candidate->id();
+ }
+ }
+ }
+
+ return result;
+}
+
+Item::Iterator::Ptr ApplyTemplate::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const TemplateMode::Ptr templateMode(effectiveMode(context));
+ const Template::Ptr &templateMatch = findTemplate(context, templateMode);
+
+ if(templateMatch)
+ return templateMatch->body->evaluateSequence(templateMatch->createContext(this, context, false));
+ else
+ {
+ /* None of our templates matched. Proceed with a built-in. */
+ const Item current(context->contextItem());
+ // TODO it can be an atomic value?
+ const QXmlNodeModelIndex::NodeKind kind(current.asNode().kind());
+
+ if(kind == QXmlNodeModelIndex::Element || kind == QXmlNodeModelIndex::Document)
+ {
+ pDebug() << "No template match, using builtin template for element() | document-node()";
+
+ const Item::Iterator::Ptr focusIterator(makeItemMappingIterator<Item>(ConstPtr(this),
+ current.asNode().iterate(QXmlNodeModelIndex::AxisChild),
+ context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(focusIterator);
+ return makeSequenceMappingIterator<Item>(ConstPtr(this), focusIterator, focus);
+ }
+ return CommonValues::emptyIterator;
+ }
+}
+
+Expression::Ptr ApplyTemplate::compress(const StaticContext::Ptr &context)
+{
+ /* If we have a mode, we will never need the default mode. */
+ if(m_mode)
+ m_defaultMode.reset();
+
+ return TemplateInvoker::compress(context);
+}
+
+SequenceType::Ptr ApplyTemplate::staticType() const
+{
+ return CommonSequenceTypes::ZeroOrMoreItems;
+}
+
+ExpressionVisitorResult::Ptr ApplyTemplate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties ApplyTemplate::properties() const
+{
+ return RequiresFocus | DisableElimination;
+}
+
+bool ApplyTemplate::configureRecursion(const CallTargetDescription::Ptr &sign)
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called.");
+ Q_UNUSED(sign);
+ return false;
+}
+
+Expression::Ptr ApplyTemplate::body() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called.");
+ return Expression::Ptr();
+}
+
+CallTargetDescription::Ptr ApplyTemplate::callTargetDescription() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called.");
+ return CallTargetDescription::Ptr();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qapplytemplate_p.h b/src/xmlpatterns/expr/qapplytemplate_p.h
new file mode 100644
index 0000000..1398945
--- /dev/null
+++ b/src/xmlpatterns/expr/qapplytemplate_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ApplyTemplate_H
+#define Patternist_ApplyTemplate_H
+
+#include "qtemplatemode_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short When combined with other components, implements
+ * @c xsl:apply-templates.
+ *
+ * Note that ApplyTemplate isn't named ApplyTemplates. The reason for this
+ * is that ApplyTemplate doesn't do the iteration part. An @c
+ * <xsl:apply-templates/> instruction is rewritten into:
+ *
+ * @code
+ * child::node/() map apply-template()
+ * @endcode
+ *
+ * Hence, this expression requires a focus, although it can consist of
+ * atomic values.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ApplyTemplate : public TemplateInvoker
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ApplyTemplate> Ptr;
+
+ /**
+ * @short @p mode may be @c null. If it is, ApplyTemplate interprets
+ * that as that it should use the #current mode.
+ *
+ * @see StaticContext::currentTemplateMode()
+ */
+ ApplyTemplate(const TemplateMode::Ptr &mode,
+ const WithParam::Hash &withParams,
+ const TemplateMode::Ptr &defaultMode);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+
+ /**
+ * The only reason this function exists, is in order to convert
+ * QXmlNodeModelIndex to QPatternist::Item. So, this is a huge
+ * performance setback. It applies for one of the builtin templates.
+ */
+ inline Item mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context) const;
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ inline TemplateMode::Ptr mode() const;
+
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign);
+ virtual Expression::Ptr body() const;
+ virtual CallTargetDescription::Ptr callTargetDescription() const;
+
+ Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ typedef QExplicitlySharedDataPointer<const ApplyTemplate> ConstPtr;
+
+ Template::Ptr findTemplate(const DynamicContext::Ptr &context,
+ const TemplateMode::Ptr &templateMode) const;
+ /**
+ * @note You typically want to use effectiveMode().
+ */
+ const TemplateMode::Ptr m_mode;
+
+ TemplateMode::Ptr m_defaultMode;
+
+ inline TemplateMode::Ptr effectiveMode(const DynamicContext::Ptr &context) const;
+ };
+
+ TemplateMode::Ptr ApplyTemplate::mode() const
+ {
+ return m_mode;
+ }
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qargumentreference.cpp b/src/xmlpatterns/expr/qargumentreference.cpp
new file mode 100644
index 0000000..d4c1bc6
--- /dev/null
+++ b/src/xmlpatterns/expr/qargumentreference.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qargumentreference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ArgumentReference::ArgumentReference(const SequenceType::Ptr &sourceType,
+ const VariableSlotID slotP) : VariableReference(slotP),
+ m_type(sourceType)
+{
+ Q_ASSERT(m_type);
+}
+
+bool ArgumentReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateEBV(context);
+}
+
+Item ArgumentReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr ArgumentReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSequence(context);
+}
+
+SequenceType::Ptr ArgumentReference::staticType() const
+{
+ return m_type;
+}
+
+ExpressionVisitorResult::Ptr ArgumentReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ArgumentReference::id() const
+{
+ return IDArgumentReference;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qargumentreference_p.h b/src/xmlpatterns/expr/qargumentreference_p.h
new file mode 100644
index 0000000..0fc51d3
--- /dev/null
+++ b/src/xmlpatterns/expr/qargumentreference_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ArgumentReference_H
+#define Patternist_ArgumentReference_H
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to an argument declared in a UserFunction.
+ *
+ * This is in other words a variable reference in side a function
+ * body, that references a function argument.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ArgumentReference : public VariableReference
+ {
+ public:
+ ArgumentReference(const SequenceType::Ptr &sourceType,
+ const VariableSlotID slot);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ private:
+ const SequenceType::Ptr m_type;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qarithmeticexpression.cpp b/src/xmlpatterns/expr/qarithmeticexpression.cpp
new file mode 100644
index 0000000..e424dc0
--- /dev/null
+++ b/src/xmlpatterns/expr/qarithmeticexpression.cpp
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qschemanumeric_p.h"
+#include "quntypedatomicconverter_p.h"
+
+#include "qarithmeticexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ArithmeticExpression::ArithmeticExpression(const Expression::Ptr &op1,
+ const AtomicMathematician::Operator op,
+ const Expression::Ptr &op2) : PairContainer(op1, op2)
+ , m_op(op)
+ , m_isCompat(false)
+{
+}
+
+Item ArithmeticExpression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operand1->evaluateSingleton(context));
+ if(!op1)
+ return Item();
+
+ const Item op2(m_operand2->evaluateSingleton(context));
+ if(!op2)
+ return Item();
+
+ return flexiblyCalculate(op1, m_op, op2, m_mather, context, this,
+ ReportContext::XPTY0004, m_isCompat);
+}
+
+/**
+ * Since ArithmeticExpression::flexiblyCalculate() creates Expression instances
+ * at runtime, we have the problem of having SourceLocationReflections for them
+ * in the case that we run into a runtime error, since the locations are always
+ * located at compile time.
+ *
+ * This class simply delegates the reflection over to an existing expression.
+ *
+ * I only managed to trigger this with "current() + 1", where current()
+ * evaluates to an invalid representation for @c xs:double.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+class DelegatingReflectionExpression : public Literal
+{
+public:
+ DelegatingReflectionExpression(const Item &item,
+ const SourceLocationReflection *const reflection) : Literal(item)
+ , m_reflection(reflection)
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const
+ {
+ return m_reflection;
+ }
+
+private:
+ const SourceLocationReflection *const m_reflection;
+};
+
+Item ArithmeticExpression::flexiblyCalculate(const Item &op1,
+ const AtomicMathematician::Operator op,
+ const Item &op2,
+ const AtomicMathematician::Ptr &mather,
+ const DynamicContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code,
+ const bool isCompat)
+{
+ if(mather)
+ return mather->calculate(op1, op, op2, context);
+
+ /* This is a very heavy code path. */
+ Expression::Ptr a1(new DelegatingReflectionExpression(op1, reflection));
+ Expression::Ptr a2(new DelegatingReflectionExpression(op2, reflection));
+
+ const AtomicMathematician::Ptr ingela(fetchMathematician(a1, a2, op, true, context, reflection, code, isCompat));
+
+ return ingela->calculate(a1->evaluateSingleton(context),
+ op,
+ a2->evaluateSingleton(context),
+ context);
+}
+
+Expression::Ptr ArithmeticExpression::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_isCompat = context->compatModeEnabled();
+
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+ const ItemType::Ptr t1(m_operand1->staticType()->itemType());
+ const ItemType::Ptr t2(m_operand2->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ return EmptySequence::create(this, context);
+ }
+
+ if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::xsAnyAtomicType == *t2 ||
+ *BuiltinTypes::numeric == *t1 ||
+ *BuiltinTypes::numeric == *t2)
+ {
+ /* The static type of (at least) one of the operands could not
+ * be narrowed further than xs:anyAtomicType, so we do the operator
+ * lookup at runtime. */
+ return me;
+ }
+
+ m_mather = fetchMathematician(m_operand1, m_operand2, m_op, true, context, this,
+ ReportContext::XPTY0004, m_isCompat);
+
+ return me;
+}
+
+AtomicMathematician::Ptr
+ArithmeticExpression::fetchMathematician(Expression::Ptr &op1,
+ Expression::Ptr &op2,
+ const AtomicMathematician::Operator op,
+ const bool issueError,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code,
+ const bool isCompat)
+{
+ ItemType::Ptr t1(op1->staticType()->itemType());
+ ItemType::Ptr t2(op2->staticType()->itemType());
+
+ if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1)
+ || (isCompat && (BuiltinTypes::xsString->xdtTypeMatches(t1)
+ || BuiltinTypes::xsDecimal->xdtTypeMatches(t1))))
+ {
+ op1 = Expression::Ptr(new UntypedAtomicConverter(op1, BuiltinTypes::xsDouble));
+ /* The types might have changed, reload. */
+ t1 = op1->staticType()->itemType();
+ }
+
+ if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2)
+ || (isCompat && (BuiltinTypes::xsString->xdtTypeMatches(t1)
+ || BuiltinTypes::xsDecimal->xdtTypeMatches(t1))))
+ {
+ op2 = Expression::Ptr(new UntypedAtomicConverter(op2, BuiltinTypes::xsDouble));
+ /* The types might have changed, reload. */
+ t2 = op2->staticType()->itemType();
+ }
+
+ const AtomicMathematicianLocator::Ptr locator
+ (static_cast<const AtomicType *>(t1.data())->mathematicianLocator());
+
+ if(!locator)
+ {
+ if(!issueError)
+ return AtomicMathematician::Ptr();
+
+ context->error(QtXmlPatterns::tr(
+ "Operator %1 cannot be used on type %2.")
+ .arg(formatKeyword(AtomicMathematician::displayName(op)))
+ .arg(formatType(context->namePool(), t1)),
+ code, reflection);
+ return AtomicMathematician::Ptr();
+ }
+
+ const AtomicMathematician::Ptr comp
+ (static_cast<const AtomicType *>(t2.data())->accept(locator, op, reflection));
+
+ if(comp)
+ return comp;
+
+ if(!issueError)
+ return AtomicMathematician::Ptr();
+
+ context->error(QtXmlPatterns::tr("Operator %1 cannot be used on "
+ "atomic values of type %2 and %3.")
+ .arg(formatKeyword(AtomicMathematician::displayName(op)))
+ .arg(formatType(context->namePool(), t1))
+ .arg(formatType(context->namePool(), t2)),
+ code, reflection);
+ return AtomicMathematician::Ptr();
+}
+
+SequenceType::Ptr ArithmeticExpression::staticType() const
+{
+ Cardinality card;
+
+ /* These variables are important because they ensure staticType() only
+ * gets called once from this function. Before, this lead to strange
+ * semi-infinite recursion involving many arithmetic expressions. */
+ const SequenceType::Ptr st1(m_operand1->staticType());
+ const SequenceType::Ptr st2(m_operand2->staticType());
+
+ if(st1->cardinality().allowsEmpty() ||
+ st2->cardinality().allowsEmpty())
+ {
+ card = Cardinality::zeroOrOne();
+ }
+ else
+ card = Cardinality::exactlyOne();
+
+ if(m_op == AtomicMathematician::IDiv)
+ return makeGenericSequenceType(BuiltinTypes::xsInteger, card);
+
+ const ItemType::Ptr t1(st1->itemType());
+ const ItemType::Ptr t2(st2->itemType());
+ ItemType::Ptr returnType;
+
+ /* Please, make this beautiful? */
+ if(BuiltinTypes::xsTime->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsDate->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsDateTime->xdtTypeMatches(t1))
+ {
+ if(BuiltinTypes::xsDuration->xdtTypeMatches(t2))
+ returnType = t1;
+ else
+ returnType = BuiltinTypes::xsDayTimeDuration;
+ }
+ else if(BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1))
+ {
+ if(m_op == AtomicMathematician::Div &&
+ BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDecimal;
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(t2))
+ returnType = BuiltinTypes::xsYearMonthDuration;
+ else
+ returnType = t2;
+ }
+ else if(BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsYearMonthDuration;
+ }
+ else if(BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1))
+ {
+ if(m_op == AtomicMathematician::Div &&
+ BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDecimal;
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(t2))
+ returnType = BuiltinTypes::xsDayTimeDuration;
+ else
+ returnType = t2;
+ }
+ else if(BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDayTimeDuration;
+ }
+ else if(BuiltinTypes::xsDouble->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsDouble->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDouble;
+ }
+ else if(BuiltinTypes::xsFloat->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsFloat->xdtTypeMatches(t2))
+ {
+ if(m_isCompat)
+ returnType = BuiltinTypes::xsFloat;
+ else
+ returnType = BuiltinTypes::xsDouble;
+ }
+ else if(BuiltinTypes::xsInteger->xdtTypeMatches(t1) &&
+ BuiltinTypes::xsInteger->xdtTypeMatches(t2))
+ {
+ if(m_isCompat)
+ returnType = BuiltinTypes::xsDouble;
+ else
+ {
+ /* "A div B numeric numeric op:numeric-divide(A, B)
+ * numeric; but xs:decimal if both operands are xs:integer" */
+ if(m_op == AtomicMathematician::Div)
+ returnType = BuiltinTypes::xsDecimal;
+ else
+ returnType = BuiltinTypes::xsInteger;
+ }
+ }
+ else if(m_isCompat && (BuiltinTypes::xsInteger->xdtTypeMatches(t1) &&
+ BuiltinTypes::xsInteger->xdtTypeMatches(t2)))
+ {
+ returnType = BuiltinTypes::xsDouble;
+ }
+ else
+ {
+ /* If typeCheck() has been called, our operands conform to expectedOperandTypes(), and
+ * the types are hence either xs:decimals, or xs:anyAtomicType(meaning the static type could
+ * not be inferred), or empty-sequence(). So we use the union of the two types. The combinations
+ * could also be wrong.*/
+ returnType = t1 | t2;
+
+ /* However, if we're called before typeCheck(), we could potentially have nodes, so we need to make
+ * sure that the type is at least atomic. */
+ if(!BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(returnType))
+ returnType = BuiltinTypes::xsAnyAtomicType;
+ }
+
+ return makeGenericSequenceType(returnType, card);
+}
+
+SequenceType::List ArithmeticExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr ArithmeticExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qarithmeticexpression_p.h b/src/xmlpatterns/expr/qarithmeticexpression_p.h
new file mode 100644
index 0000000..a1621f7
--- /dev/null
+++ b/src/xmlpatterns/expr/qarithmeticexpression_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ArithmeticExpression_H
+#define Patternist_ArithmeticExpression_H
+
+#include "qatomicmathematician_p.h"
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements arithmetics, such as multiplication and subtraction.
+ *
+ *
+ * Optimizations: there's some operator/value combos that are no ops. For
+ * instance, 0 + <value>, which is the case of unary plus. We can't compile
+ * those away early due to that type checks needs to be done but one can
+ * check for them in compress().
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-arithmetic">XML Path Language
+ * (XPath) 2.0, 3.4 Arithmetic Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT ArithmeticExpression : public PairContainer
+ {
+ public:
+ ArithmeticExpression(const Expression::Ptr &operand1,
+ const AtomicMathematician::Operator op,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ AtomicMathematician::Operator operatorID() const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ static Item flexiblyCalculate(const Item &op1,
+ const AtomicMathematician::Operator op,
+ const Item &op2,
+ const AtomicMathematician::Ptr &mather,
+ const DynamicContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code = ReportContext::XPTY0004,
+ const bool isCompat = false);
+
+ static AtomicMathematician::Ptr
+ fetchMathematician(Expression::Ptr &t1,
+ Expression::Ptr &t2,
+ const AtomicMathematician::Operator op,
+ const bool issueError,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code = ReportContext::XPTY0004,
+ const bool isCompat = false);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ protected:
+
+ private:
+ const AtomicMathematician::Operator m_op;
+ AtomicMathematician::Ptr m_mather;
+ bool m_isCompat;
+ };
+
+ inline AtomicMathematician::Operator ArithmeticExpression::operatorID() const
+ {
+ return m_op;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qattributeconstructor.cpp b/src/xmlpatterns/expr/qattributeconstructor.cpp
new file mode 100644
index 0000000..fa41afd
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributeconstructor.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+#include "qqnamevalue_p.h"
+
+#include "qattributeconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AttributeConstructor::AttributeConstructor(const Expression::Ptr &op1,
+ const Expression::Ptr &op2) : PairContainer(op1, op2)
+{
+}
+
+QString AttributeConstructor::processValue(const QXmlName name,
+ const Item &value)
+{
+ if(!value)
+ return QString();
+ else if(name == QXmlName(StandardNamespaces::xml, StandardLocalNames::id))
+ return value.stringValue().simplified();
+ else
+ return value.stringValue();
+}
+
+Item AttributeConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item nameItem(m_operand1->evaluateSingleton(context));
+ const Item content(m_operand2->evaluateSingleton(context));
+
+ const QXmlName name(nameItem.as<QNameValue>()->qName());
+ const QString value(processValue(name, content));
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+
+ nodeBuilder->attribute(name, QStringRef(&value));
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void AttributeConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+ const Item nameItem(m_operand1->evaluateSingleton(context));
+
+ const Item content(m_operand2->evaluateSingleton(context));
+ const QXmlName name(nameItem.as<QNameValue>()->qName());
+ const QString value(processValue(name, content));
+
+ receiver->attribute(name, QStringRef(&value));
+}
+
+SequenceType::Ptr AttributeConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneAttribute;
+}
+
+SequenceType::List AttributeConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneQName);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties AttributeConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+AttributeConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID AttributeConstructor::id() const
+{
+ return IDAttributeConstructor;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qattributeconstructor_p.h b/src/xmlpatterns/expr/qattributeconstructor_p.h
new file mode 100644
index 0000000..055ad7f
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributeconstructor_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AttributeConstructor_H
+#define Patternist_AttributeConstructor_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs an element node. This covers both computed and directly constructed
+ * element nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class AttributeConstructor : public PairContainer
+ {
+ public:
+ AttributeConstructor(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:QName, and the second
+ * argument can be zero or more items.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always IDAttributeConstructor.
+ */
+ virtual ID id() const;
+
+ virtual Properties properties() const;
+
+ private:
+ static inline QString processValue(const QXmlName name,
+ const Item &value);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qattributenamevalidator.cpp b/src/xmlpatterns/expr/qattributenamevalidator.cpp
new file mode 100644
index 0000000..1625bc1
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributenamevalidator.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+
+#include "qattributenamevalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AttributeNameValidator::AttributeNameValidator(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item AttributeNameValidator::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand->evaluateSingleton(context));
+ const QXmlName qName(name.as<QNameValue>()->qName());
+
+ if(qName.namespaceURI() == StandardNamespaces::xmlns)
+ {
+ context->error(QtXmlPatterns::tr("The namespace URI in the name for a "
+ "computed attribute cannot be %1.")
+ .arg(formatURI(CommonNamespaces::XMLNS)),
+ ReportContext::XQDY0044, this);
+ return Item(); /* Silence warning. */
+ }
+ else if(qName.namespaceURI() == StandardNamespaces::empty &&
+ qName.localName() == StandardLocalNames::xmlns)
+ {
+ context->error(QtXmlPatterns::tr("The name for a computed attribute "
+ "cannot have the namespace URI %1 "
+ "with the local name %2.")
+ .arg(formatURI(CommonNamespaces::XMLNS))
+ .arg(formatKeyword("xmlns")),
+ ReportContext::XQDY0044, this);
+ return Item(); /* Silence warning. */
+ }
+ else if(!qName.hasPrefix() && qName.hasNamespace())
+ {
+ return Item(QNameValue::fromValue(context->namePool(),
+ QXmlName(qName.namespaceURI(), qName.localName(), StandardPrefixes::ns0)));
+ }
+ else
+ return name;
+}
+
+SequenceType::Ptr AttributeNameValidator::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List AttributeNameValidator::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneQName);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr AttributeNameValidator::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qattributenamevalidator_p.h b/src/xmlpatterns/expr/qattributenamevalidator_p.h
new file mode 100644
index 0000000..ddf05ec
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributenamevalidator_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AttributeNameValidator_H
+#define Patternist_AttributeNameValidator_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Ensures the lexical space of the string value of the Item returned
+ * from its child Expression is an NCName. Also possibly changes the name
+ * by generating a prefix if one is needed.
+ *
+ * @note It doesn't actually construct an @c xs:NCName. It only ensures the lexical
+ * space is an @c NCName. The atomic value can be of any string type, such as @c xs:untypedAtomic
+ * of @c xs:string.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class AttributeNameValidator : public SingleContainer
+ {
+ public:
+ AttributeNameValidator(const Expression::Ptr &source);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns the static type of its operand. This is returned as opposed
+ * CommonSequenceTypes::ExactlyOneQName, since the operand might return a subtype
+ * of @c xs:QName.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qaxisstep.cpp b/src/xmlpatterns/expr/qaxisstep.cpp
new file mode 100644
index 0000000..40fe694
--- /dev/null
+++ b/src/xmlpatterns/expr/qaxisstep.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qparentnodeaxis_p.h"
+
+#include "qaxisstep_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ /**
+ * This operator is needed for the s_whenAxisNodeKindEmpty array. The @c int constructors
+ * ensure we invoke another operator| such that we don't get an infinite loop.
+ */
+ static inline QXmlNodeModelIndex::NodeKind operator|(const QXmlNodeModelIndex::NodeKind &op1, const QXmlNodeModelIndex::NodeKind &op2)
+ {
+ return QXmlNodeModelIndex::NodeKind(int(op1) | int(op2));
+ }
+}
+
+/**
+ * @note The order is significant. It is of the same order as the values in QXmlNodeModelIndex::Axis is declared.
+ */
+const QXmlNodeModelIndex::NodeKind AxisStep::s_whenAxisNodeKindEmpty[] =
+{
+ QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // child;
+ QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // descendant;
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace,// attribute;
+ QXmlNodeModelIndex::NodeKind(0), // self;
+ QXmlNodeModelIndex::NodeKind(0), // descendant-or-self;
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // namespace;
+ QXmlNodeModelIndex::Document, // following;
+ QXmlNodeModelIndex::Document, // parent;
+ QXmlNodeModelIndex::Document, // ancestor
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Namespace, // preceding-sibling;
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Namespace, // following-sibling;
+ QXmlNodeModelIndex::Document, // preceding;
+ QXmlNodeModelIndex::NodeKind(0) // ancestor-or-self;
+};
+
+bool AxisStep::isAlwaysEmpty(const QXmlNodeModelIndex::Axis axis, const QXmlNodeModelIndex::NodeKind nodeKind)
+{
+ return (s_whenAxisNodeKindEmpty[(1 >> axis) - 1] & nodeKind) != 0;
+}
+
+AxisStep::AxisStep(const QXmlNodeModelIndex::Axis a,
+ const ItemType::Ptr &nt) : m_axis(a),
+ m_nodeTest(nt)
+{
+ Q_ASSERT(m_nodeTest);
+ Q_ASSERT_X(BuiltinTypes::node->xdtTypeMatches(m_nodeTest), Q_FUNC_INFO,
+ "We assume we're a node type.");
+}
+
+Item AxisStep::mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(!node.isNull());
+ Q_ASSERT(Item(node).isNode());
+ Q_ASSERT(Item(node));
+ Q_UNUSED(context);
+
+ if(m_nodeTest->itemMatches(Item(node)))
+ return Item(node);
+ else
+ return Item();
+}
+
+Item::Iterator::Ptr AxisStep::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ /* If we don't have a focus, it's either a bug or our parent isn't a Path
+ * that have advanced the focus iterator. Hence, attempt to advance the focus on our own. */
+ if(!context->contextItem())
+ context->focusIterator()->next();
+
+ Q_ASSERT(context->contextItem());
+
+ const QXmlNodeModelIndex::Iterator::Ptr source(context->contextItem().asNode().iterate(m_axis));
+
+ return makeItemMappingIterator<Item>(ConstPtr(this), source, context);
+}
+
+Item AxisStep::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ /* If we don't have a focus, it's either a bug or our parent isn't a Path
+ * that have advanced the focus iterator. Hence, attempt to advance the focus on our own. */
+ if(!context->contextItem())
+ context->focusIterator()->next();
+
+ Q_ASSERT(context->contextItem());
+
+ const QXmlNodeModelIndex::Iterator::Ptr it(context->contextItem().asNode().iterate(m_axis));
+ QXmlNodeModelIndex next(it->next());
+
+ while(!next.isNull())
+ {
+ const Item candidate(mapToItem(next, context));
+
+ if(candidate)
+ return candidate;
+ else
+ next = it->next();
+ };
+
+ return Item();
+}
+
+Expression::Ptr AxisStep::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(m_axis == QXmlNodeModelIndex::AxisParent && *m_nodeTest == *BuiltinTypes::node)
+ {
+ /* We only rewrite parent::node() to ParentNodeAxis. */
+ return rewrite(Expression::Ptr(new ParentNodeAxis()), context)->typeCheck(context, reqType);
+ }
+ /* TODO temporarily disabled
+ else if(isAlwaysEmpty(m_axis, static_cast<const AnyNodeType *>(m_nodeTest.data())->nodeKind()))
+ return EmptySequence::create(this, context);
+ */
+ else
+ return EmptyContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr AxisStep::staticType() const
+{
+ Cardinality cardinality;
+
+ if(m_axis == QXmlNodeModelIndex::AxisSelf || m_axis == QXmlNodeModelIndex::AxisParent)
+ cardinality = Cardinality::zeroOrOne();
+ else
+ cardinality = Cardinality::zeroOrMore();
+
+ return makeGenericSequenceType(m_nodeTest,
+ cardinality);
+}
+
+SequenceType::List AxisStep::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+ return result;
+}
+
+Expression::Properties AxisStep::properties() const
+{
+ return RequiresContextItem | DisableElimination;
+}
+
+ItemType::Ptr AxisStep::expectedContextItemType() const
+{
+ return BuiltinTypes::node;
+}
+
+ExpressionVisitorResult::Ptr AxisStep::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QXmlNodeModelIndex::Axis AxisStep::axis() const
+{
+ return m_axis;
+}
+
+QString AxisStep::axisName(const QXmlNodeModelIndex::Axis axis)
+{
+ const char *result = 0;
+
+ switch(axis)
+ {
+ /* These must not be translated. */
+ case QXmlNodeModelIndex::AxisAncestorOrSelf: result = "ancestor-or-self"; break;
+ case QXmlNodeModelIndex::AxisAncestor: result = "ancestor"; break;
+ case QXmlNodeModelIndex::AxisAttributeOrTop: result = "attribute-or-top"; break;
+ case QXmlNodeModelIndex::AxisAttribute: result = "attribute"; break;
+ case QXmlNodeModelIndex::AxisChildOrTop: result = "child-or-top"; break;
+ case QXmlNodeModelIndex::AxisChild: result = "child"; break;
+ case QXmlNodeModelIndex::AxisDescendantOrSelf: result = "descendant-or-self"; break;
+ case QXmlNodeModelIndex::AxisDescendant: result = "descendant"; break;
+ case QXmlNodeModelIndex::AxisFollowing: result = "following"; break;
+ case QXmlNodeModelIndex::AxisFollowingSibling: result = "following-sibling"; break;
+ case QXmlNodeModelIndex::AxisNamespace: result = "namespace"; break;
+ case QXmlNodeModelIndex::AxisParent: result = "parent"; break;
+ case QXmlNodeModelIndex::AxisPreceding: result = "preceding"; break;
+ case QXmlNodeModelIndex::AxisPrecedingSibling: result = "preceding-sibling"; break;
+ case QXmlNodeModelIndex::AxisSelf: result = "self"; break;
+ }
+
+ Q_ASSERT_X(result, Q_FUNC_INFO, "An unknown axis type was apparently encountered.");
+ return QString::fromLatin1(result);
+}
+
+PatternPriority AxisStep::patternPriority() const
+{
+ return static_cast<const AnyNodeType *>(m_nodeTest.data())->patternPriority();
+}
+
+Expression::ID AxisStep::id() const
+{
+ return IDAxisStep;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qaxisstep_p.h b/src/xmlpatterns/expr/qaxisstep_p.h
new file mode 100644
index 0000000..8f2ae27
--- /dev/null
+++ b/src/xmlpatterns/expr/qaxisstep_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AxisStep_H
+#define Patternist_AxisStep_H
+
+#include "qemptycontainer_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A step in a path expression that with an axis and a node test evaluates
+ * to a sequence of nodes from the context item.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT AxisStep : public EmptyContainer
+ {
+ public:
+ AxisStep(const QXmlNodeModelIndex::Axis axis,
+ const ItemType::Ptr &nodeTest);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * Returns @p node if it matches the node test this step is using, otherwise @c null.
+ */
+ inline Item mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Rewrites to ParentNodeAxis, if possible.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always BuiltinTypes::node;
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+
+ /**
+ * @returns the axis this step is using.
+ */
+ QXmlNodeModelIndex::Axis axis() const;
+
+ /**
+ * @returns the node test this step is using.
+ */
+ inline ItemType::Ptr nodeTest() const
+ {
+ return m_nodeTest;
+ }
+
+ void setNodeTest(const ItemType::Ptr &nev)
+ {
+ m_nodeTest = nev;
+ }
+
+ /**
+ * @short Prints the EBNF name corresponding to @p axis.
+ *
+ * For instance, for QXmlNodeModelIndex::Child, "child" is returned.
+ *
+ * Apart from being used in this class, it is used in the SDK.
+ */
+ static QString axisName(const QXmlNodeModelIndex::Axis axis);
+
+ virtual ID id() const;
+ virtual PatternPriority patternPriority() const;
+
+ inline void setAxis(const QXmlNodeModelIndex::Axis newAxis);
+
+ private:
+ typedef QExplicitlySharedDataPointer<const AxisStep> ConstPtr;
+
+ static const QXmlNodeModelIndex::NodeKind s_whenAxisNodeKindEmpty[];
+
+ /**
+ * @returns @c true when the axis @p axis and a node test testing node of
+ * type @p nodeKind always produces an empty sequence. One such example
+ * is <tt>attribute::comment()</tt>.
+ */
+ static bool isAlwaysEmpty(const QXmlNodeModelIndex::Axis axis,
+ const QXmlNodeModelIndex::NodeKind nodeKind);
+
+ /**
+ * The reason this variable is mutable, is that in the case of XSL-T patterns,
+ * we do quite some reordering.
+ */
+ QXmlNodeModelIndex::Axis m_axis;
+ ItemType::Ptr m_nodeTest;
+ };
+
+ void AxisStep::setAxis(const QXmlNodeModelIndex::Axis newAxis)
+ {
+ m_axis = newAxis;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcachecells_p.h b/src/xmlpatterns/expr/qcachecells_p.h
new file mode 100644
index 0000000..ec9ea8e
--- /dev/null
+++ b/src/xmlpatterns/expr/qcachecells_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CacheCells_H
+#define Patternist_CacheCells_H
+
+#include <QList>
+#include <QVector>
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents a cache entry for a single Item,
+ * as opposed to for a sequence of items.
+ *
+ * A characteristic of the ItemCacheCell is that it has two states:
+ * either its full or it's not, since it only deals with a single
+ * item.
+ *
+ * Remember that cachedItem doesn't tell the state of the ItemCacheCell.
+ * For instance, it can have a null pointer, the empty sequence, and that
+ * can be the value of its cache.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ItemCacheCell
+ {
+ public:
+ typedef QList<ItemCacheCell> List;
+ typedef QVector<ItemCacheCell> Vector;
+ enum CacheState
+ {
+ Full,
+ Empty
+ };
+
+ inline ItemCacheCell() : cacheState(Empty)
+ {
+ }
+
+ Item cachedItem;
+ CacheState cacheState;
+ };
+
+ /**
+ * @short Represents a cache entry for a sequence of items.
+ *
+ * As opposed to ItemCacheCell, ItemSequenceCacheCell can be partially
+ * populated: e.g, four items is in the cache while three remains in the
+ * source. For that reason ItemSequenceCacheCell in addition to the source
+ * also carried an QAbstractXmlForwardIterator which is the source, such
+ * that it can continue to populate the cache when it runs out.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ItemSequenceCacheCell
+ {
+ public:
+ typedef QList<ItemSequenceCacheCell> List;
+ typedef QVector<ItemSequenceCacheCell> Vector;
+
+ enum CacheState
+ {
+ Full,
+ Empty,
+ PartiallyPopulated
+ };
+
+ inline ItemSequenceCacheCell() : cacheState(Empty)
+ , inUse(false)
+ {
+ }
+
+ Item::List cachedItems;
+ Item::Iterator::Ptr sourceIterator;
+ CacheState cacheState;
+ /**
+ * In XSL-T, we can have circularity which we cannot detect statically.
+ * For instance, a global variable invokes a template, and the template
+ * uses the variable. We can't detect that, because we can't figure out
+ * what template will be invoked.
+ *
+ * For solution we have this toggle, which is set temporarily on the
+ * cell such that EvaluationCache can detect whether it's trashing
+ * itself.
+ *
+ * One might think that it would be sufficient to flag usage of the
+ * variable in an arbitrary template, but that would also flag valid
+ * cases.
+ */
+ bool inUse;
+ };
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::ItemCacheCell, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QPatternist::ItemSequenceCacheCell, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcallsite.cpp b/src/xmlpatterns/expr/qcallsite.cpp
new file mode 100644
index 0000000..7137bb4
--- /dev/null
+++ b/src/xmlpatterns/expr/qcallsite.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcallsite_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CallSite::CallSite(const QXmlName &name) : m_isRecursive(false)
+ , m_name(name)
+{
+}
+
+QXmlName CallSite::name() const
+{
+ return m_name;
+}
+
+bool CallSite::isRecursive() const
+{
+ return m_isRecursive;
+}
+
+void CallSite::setIsRecursive(const bool value)
+{
+ m_isRecursive = value;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcallsite_p.h b/src/xmlpatterns/expr/qcallsite_p.h
new file mode 100644
index 0000000..6c0013c
--- /dev/null
+++ b/src/xmlpatterns/expr/qcallsite_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CallSite_H
+#define Patternist_CallSite_H
+
+#include "qunlimitedcontainer_p.h"
+#include "qcalltargetdescription_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Abstract base-class for Expression instances that are callsites
+ * to other components, such as templates or user functions.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class CallSite : public UnlimitedContainer
+ {
+ public:
+ QXmlName name() const;
+ bool isRecursive() const;
+ void setIsRecursive(const bool value);
+
+ /**
+ * Called in the earliest stages of the compilation process. @p sign can
+ * be any function signature for a user declared function. If @p sign
+ * matches this UserFunctionCallsite, it means the UserFunction represented
+ * by @p sign is recursive and that this UserFunctionCallsite should take
+ * appropriate measures.
+ *
+ * @returns @c true if is recursive, otherwise @c false
+ */
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign) = 0;
+
+ /**
+ * @short Returns the body of the function/template/component that is
+ * being called.
+ */
+ virtual Expression::Ptr body() const = 0;
+
+ virtual CallTargetDescription::Ptr callTargetDescription() const = 0;
+
+ protected:
+ CallSite(const QXmlName &name = QXmlName());
+
+ private:
+ Q_DISABLE_COPY(CallSite)
+ bool m_isRecursive;
+ const QXmlName m_name;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcalltargetdescription.cpp b/src/xmlpatterns/expr/qcalltargetdescription.cpp
new file mode 100644
index 0000000..0e14469
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltargetdescription.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcallsite_p.h"
+
+#include "qcalltargetdescription_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CallTargetDescription::CallTargetDescription(const QXmlName &name) : m_name(name)
+{
+ Q_ASSERT(!m_name.isNull());
+}
+
+QXmlName CallTargetDescription::name() const
+{
+ return m_name;
+}
+
+void CallTargetDescription::checkArgumentsCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr callsite)
+{
+ /* Check the arguments. */
+ const Expression::List ops(callsite->operands());
+ const Expression::List::const_iterator end(ops.constEnd());
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ checkCallsiteCircularity(signList, *it);
+}
+
+void CallTargetDescription::checkCallsiteCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr expr)
+{
+ Q_ASSERT(expr);
+
+ if(expr->is(Expression::IDUserFunctionCallsite))
+ {
+ CallTargetDescription::List::const_iterator it(signList.constBegin());
+ const CallTargetDescription::List::const_iterator end(signList.constEnd());
+ CallSite *const callsite = static_cast<CallSite *>(expr.data());
+
+ for(; it != end; ++it)
+ {
+ if(callsite->configureRecursion(*it))
+ {
+ /* A callsite inside the function body to the function. This user function
+ * is recursive if it's to the same function, in other words. Which it was
+ * if configureRecursion() returned true. */
+
+ /* Now we continue and check the arguments of the callsite. That is, the arguments.
+ * This catches for instance local:foo(local:foo(3)). */
+ checkArgumentsCircularity(signList, expr);
+ return;
+ }
+ }
+ /* Check the body of the function so this callsite isn't "indirectly" a
+ * recursive call to the function we're checking. XQTS test case
+ * default_namespace-011 is an example of this. */
+ signList.append(callsite->callTargetDescription());
+ checkCallsiteCircularity(signList, callsite->body());
+ }
+
+ checkArgumentsCircularity(signList, expr); /* We're done in this case. */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcalltargetdescription_p.h b/src/xmlpatterns/expr/qcalltargetdescription_p.h
new file mode 100644
index 0000000..ac614be
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltargetdescription_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CallTargetDescription_H
+#define Patternist_CallTargetDescription_H
+
+template<typename Key, typename Value> class QHash;
+template<typename T> class QList;
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class CallSite;
+
+ /**
+ * @short Contains metadata for a callable component, such as a function or
+ * template.
+ *
+ * CallTargetDescription can be used directly and is so for templates, but
+ * can also be sub-classed which FunctionSignature do.
+ *
+ * @ingroup Patternist_expr
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT CallTargetDescription : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<CallTargetDescription> Ptr;
+ typedef QList<Ptr> List;
+
+ CallTargetDescription(const QXmlName &name);
+
+ /**
+ * The function's name. For example, the name of the signature
+ * <tt>fn:string() as xs:string</tt> is <tt>fn:string</tt>.
+ */
+ QXmlName name() const;
+
+ /**
+ * Flags callsites to be aware of their recursion by calling
+ * UserFunctionCallsite::configureRecursion(), if that is the case.
+ *
+ * @note We pass @p expr by value here intentionally.
+ */
+ static void checkCallsiteCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr expr);
+ private:
+ /**
+ * Helper function for checkCallsiteCircularity(). If C++ allowed it,
+ * it would have been local to it.
+ */
+ static void checkArgumentsCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr callsite);
+
+ Q_DISABLE_COPY(CallTargetDescription)
+ const QXmlName m_name;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/expr/qcalltemplate.cpp b/src/xmlpatterns/expr/qcalltemplate.cpp
new file mode 100644
index 0000000..f16ffcf
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltemplate.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qcalltemplate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CallTemplate::CallTemplate(const QXmlName &name,
+ const WithParam::Hash &withParams) : TemplateInvoker(withParams, name)
+{
+}
+
+Item::Iterator::Ptr CallTemplate::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_template);
+ return m_template->body->evaluateSequence(m_template->createContext(this, context, true));
+}
+
+bool CallTemplate::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_template);
+ return m_template->body->evaluateEBV(m_template->createContext(this, context, true));
+}
+
+void CallTemplate::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_template);
+ m_template->body->evaluateToSequenceReceiver(m_template->createContext(this, context, true));
+}
+
+Expression::Ptr CallTemplate::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* Check XTSE0680, that every @c xsl:with-param has a corresponding @c
+ * xsl:param declaration. */
+ {
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin());
+ it != end;
+ ++it)
+ {
+ if(!VariableDeclaration::contains(m_template->templateParameters, it.value()->name()))
+ Template::raiseXTSE0680(context, it.value()->name(), this);
+ }
+ }
+
+ const Expression::Ptr me(TemplateInvoker::typeCheck(context, reqType));
+
+ const VariableDeclaration::List args(m_template->templateParameters);
+ const VariableDeclaration::List::const_iterator end(args.constEnd());
+ VariableDeclaration::List::const_iterator it(args.constBegin());
+
+ for(; it != end; ++it)
+ {
+ // TODO
+ Q_ASSERT((*it)->sequenceType);
+ }
+
+ return me;
+}
+
+Expression::Properties CallTemplate::properties() const
+{
+ Q_ASSERT(!m_template || m_template->body);
+
+ /* We may be called before our m_template is resolved, namely when we're
+ * the body of a variable. In that case querytransformparser.ypp will
+ * manually call TypeChecker::applyFunctionConversion(), which is before
+ * ExpressionFactory::createExpression() has resolved us. */
+ if(m_template && !isRecursive())
+ return m_template->properties();
+ else
+ return Properties();
+}
+
+Expression::Properties CallTemplate::dependencies() const
+{
+ if(m_template && !isRecursive())
+ return m_template->dependencies();
+ else
+ return Properties();
+}
+
+SequenceType::Ptr CallTemplate::staticType() const
+{
+ return CommonSequenceTypes::ZeroOrMoreItems;
+}
+
+ExpressionVisitorResult::Ptr CallTemplate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+bool CallTemplate::configureRecursion(const CallTargetDescription::Ptr &sign)
+{
+ Q_UNUSED(sign);
+ return false;
+}
+
+Expression::Ptr CallTemplate::body() const
+{
+ return m_template->body;
+}
+
+CallTargetDescription::Ptr CallTemplate::callTargetDescription() const
+{
+ return CallTargetDescription::Ptr();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcalltemplate_p.h b/src/xmlpatterns/expr/qcalltemplate_p.h
new file mode 100644
index 0000000..df67121
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltemplate_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CallTemplate_H
+#define Patternist_CallTemplate_H
+
+#include "qcallsite_p.h"
+#include "qtemplateinvoker_p.h"
+#include "qtemplate_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements @c xsl:call-template.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CallTemplate : public TemplateInvoker
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<CallTemplate> Ptr;
+
+ CallTemplate(const QXmlName &name,
+ const WithParam::Hash &withParams);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ virtual Properties dependencies() const;
+
+ /**
+ * This is a bit complicated by that we have two required types, one
+ * specified by @c xsl:param in the template declaration, and one on @c
+ * xsl:with-param.
+ *
+ * @see UserFunctionCallsite::expectedOperandTypes()
+ * @see <a href="http://www.w3.org/TR/xslt20/#with-param">XSL
+ * Transformations (XSLT) Version 2.0, 10.1.1 Passing Parameters to Templates</a>
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+
+ inline void setTemplate(const Template::Ptr &templ)
+ {
+ m_template = templ;
+ }
+
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign);
+ virtual Expression::Ptr body() const;
+ virtual CallTargetDescription::Ptr callTargetDescription() const;
+ private:
+ Template::Ptr m_template;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcastableas.cpp b/src/xmlpatterns/expr/qcastableas.cpp
new file mode 100644
index 0000000..65b5305
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastableas.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qitem_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qcastableas_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CastableAs::CastableAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &tType) : SingleContainer(operand),
+ m_targetType(tType)
+{
+ Q_ASSERT(tType);
+ Q_ASSERT(!tType->cardinality().allowsMany());
+ Q_ASSERT(tType->itemType()->isAtomicType());
+}
+
+bool CastableAs::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ Item item;
+
+ if(m_operand->staticType()->cardinality().allowsMany())
+ {
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ item = it->next();
+
+ if(it->next())
+ return false;
+ }
+ else
+ item = m_operand->evaluateSingleton(context);
+
+ if(item)
+ return !cast(item, context).as<AtomicValue>()->hasError();
+ else
+ return m_targetType->cardinality().allowsEmpty();
+}
+
+Expression::Ptr CastableAs::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me != this) /* We already managed to const fold, how convenient. */
+ return me;
+
+ const AtomicType::Ptr t(m_targetType->itemType());
+
+ const SequenceType::Ptr opType(m_operand->staticType());
+
+ /* Casting to these always succeeds, assuming the cardinality also matches,
+ * although the cardinality can fail. */
+ if(( *t == *BuiltinTypes::xsString
+ || *t == *BuiltinTypes::xsUntypedAtomic
+ || *t == *opType->itemType())
+ &&(m_targetType->cardinality().isMatch(opType->cardinality())))
+ {
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ }
+ else
+ return me;
+}
+
+Expression::Ptr CastableAs::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ checkTargetType(context);
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+
+ return me;
+ if(BuiltinTypes::xsQName->xdtTypeMatches(m_targetType->itemType()))
+ {
+ const SequenceType::Ptr seqt(m_operand->staticType());
+ /* We can cast a string literal, an xs:QName value, and an
+ * empty sequence(if empty is allowed), to xs:QName. */
+ if(m_operand->is(IDStringValue) ||
+ BuiltinTypes::xsQName->xdtTypeMatches(seqt->itemType()) ||
+ (*seqt->itemType() == *CommonSequenceTypes::Empty && m_targetType->cardinality().allowsEmpty()))
+ {
+ return wrapLiteral(CommonValues::BooleanTrue, context, this)->typeCheck(context, reqType);
+ }
+ else
+ return wrapLiteral(CommonValues::BooleanFalse, context, this)->typeCheck(context, reqType);
+ }
+ else
+ {
+ /* Let the CastingPlatform look up its AtomicCaster. */
+ prepareCasting(context, m_operand->staticType()->itemType());
+
+ return me;
+ }
+}
+
+SequenceType::List CastableAs::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ return result;
+}
+
+SequenceType::Ptr CastableAs::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr CastableAs::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcastableas_p.h b/src/xmlpatterns/expr/qcastableas_p.h
new file mode 100644
index 0000000..fe216b1
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastableas_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CastableAs_H
+#define Patternist_CastableAs_H
+
+#include "qsinglecontainer_p.h"
+#include "qcastingplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's <tt>castable as</tt> expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-castable">XML Path Language
+ * (XPath) 2.0, 3.10.3 Castable</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CastableAs : public SingleContainer,
+ public CastingPlatform<CastableAs, false>
+ {
+ public:
+ CastableAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &targetType);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+
+ /**
+ * Overridden to const fold to @c true when the target type
+ * is a type which casting to always succeeds. This is
+ * the type identical to the target type, <tt>xs:string</tt>,
+ * and <tt>xs:untypedAtomic</tt>.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline ItemType::Ptr targetType() const
+ {
+ return m_targetType->itemType();
+ }
+
+ private:
+ const SequenceType::Ptr m_targetType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcastas.cpp b/src/xmlpatterns/expr/qcastas.cpp
new file mode 100644
index 0000000..741d052
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastas.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcardinalityverifier_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qqnameconstructor_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qcastas_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CastAs::CastAs(const Expression::Ptr &source,
+ const SequenceType::Ptr &tType) : SingleContainer(source),
+ m_targetType(tType)
+{
+ Q_ASSERT(source);
+ Q_ASSERT(tType);
+ Q_ASSERT(!tType->cardinality().allowsMany());
+ Q_ASSERT(tType->itemType()->isAtomicType());
+}
+
+Item CastAs::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ const Item val(m_operand->evaluateSingleton(context));
+
+ if(val)
+ return cast(val, context);
+ else
+ {
+ /* No item supplied, let's handle the cardinality part. */
+
+ if(m_targetType->cardinality().allowsEmpty())
+ return Item();
+ else
+ {
+ Q_ASSERT(context);
+ context->error(QtXmlPatterns::tr("Type error in cast, expected %1, "
+ "received %2.")
+ .arg(formatType(Cardinality::exactlyOne()))
+ .arg(formatType(Cardinality::empty())),
+ ReportContext::XPTY0004, this);
+ return Item();
+ }
+ }
+}
+
+Expression::Ptr CastAs::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ checkTargetType(context);
+ const SequenceType::Ptr seqt(m_operand->staticType());
+ ItemType::Ptr t(seqt->itemType());
+
+ /* Special case xs:QName */
+ if(BuiltinTypes::xsQName->xdtTypeMatches(m_targetType->itemType()))
+ {
+ /* Ok, We're casting to xs:QName. */
+ if(m_operand->is(IDStringValue)) /* A valid combination, let's do the cast. */
+ return castToQName(context)->typeCheck(context, reqType);
+ else if(BuiltinTypes::xsQName->xdtTypeMatches(t))
+ return m_operand->typeCheck(context, reqType);
+ else if(seqt->cardinality().isEmpty() && m_targetType->cardinality().allowsEmpty())
+ return EmptySequence::create(this, context);
+ else if(!(seqt->cardinality().isEmpty() && !m_targetType->cardinality().allowsEmpty()))
+ {
+ context->error(QtXmlPatterns::tr("When casting to %1 or types "
+ "derived from it, the source "
+ "value must be of the same type, "
+ "or it must be a string literal. "
+ "Type %2 is not allowed.")
+ .arg(formatType(context->namePool(), BuiltinTypes::xsQName))
+ .arg(formatType(context->namePool(), seqt)),
+ ReportContext::XPTY0004, this);
+ return Expression::Ptr(this);
+ }
+ }
+
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+ /* Type may have changed, such as that atomization has been applied. */
+ t = m_operand->staticType()->itemType();
+
+ if(m_targetType->itemType()->xdtTypeMatches(t) &&
+ !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t) &&
+ !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t))
+ { /* At least casting is superflorous. */
+ if(m_operand->staticType()->cardinality().isMatch(m_targetType->cardinality()))
+ return m_operand; /* The whole cast expression is redundant. */
+ else
+ { /* Only cardinality check is needed, rewrite to CardinalityVerifier. */
+ return Expression::Ptr(new CardinalityVerifier(m_operand,
+ m_targetType->cardinality(),
+ ReportContext::FORG0001));
+ }
+ }
+
+ /* Let the CastingPlatform look up its AtomicCaster. */
+ prepareCasting(context, t);
+
+ return me;
+}
+
+Expression::Ptr CastAs::compress(const StaticContext::Ptr &context)
+{
+ /* Simplify casts to itself. */
+ if(*m_targetType->itemType() == *m_operand->staticType()->itemType())
+ return m_operand->compress(context);
+ else
+ return SingleContainer::compress(context);
+}
+
+Expression::Ptr CastAs::castToQName(const StaticContext::Ptr &context) const
+{
+ /* Apply the whitespace facet by calling trimmed(). */
+ /* We can assume m_operand is an Expression because this is a requirement
+ * for casting to xs:QName. */
+ const QString lexQName(m_operand->as<Literal>()->item().as<AtomicValue>()->stringValue().trimmed());
+
+ const QXmlName
+ expName(QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::FORG0001,
+ ReportContext::FONS0004>(lexQName,
+ context,
+ context->namespaceBindings(), this));
+ return wrapLiteral(toItem(QNameValue::fromValue(context->namePool(), expName)), context, this);
+}
+
+SequenceType::Ptr CastAs::staticType() const
+{
+ if(m_operand->staticType()->cardinality().allowsEmpty())
+ return m_targetType;
+ else
+ return makeGenericSequenceType(m_targetType->itemType(),
+ Cardinality::exactlyOne());
+}
+
+SequenceType::List CastAs::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ if(m_targetType->cardinality().allowsEmpty())
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ else
+ result.append(CommonSequenceTypes::ExactlyOneAtomicType);
+
+ return result;
+}
+
+ExpressionVisitorResult::Ptr CastAs::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcastas_p.h b/src/xmlpatterns/expr/qcastas_p.h
new file mode 100644
index 0000000..892b064
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastas_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CastAs_H
+#define Patternist_CastAs_H
+
+#include "qsinglecontainer_p.h"
+#include "qcastingplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's <tt>cast as</tt> expression.
+ *
+ * Implements the casting expression, such as <tt>'3' cast as xs:integer</tt>. This class also
+ * implements constructor functions, which are created in the ConstructorFunctionsFactory.
+ *
+ * CastAs uses CastingPlatform for carrying out the actual casting.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#casting">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 7 Casting</a>
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-cast">XML Path Language
+ * (XPath) 2.0, 3.10.2 Cast</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CastAs : public SingleContainer,
+ public CastingPlatform<CastAs, true /* issueError */>
+ {
+ public:
+
+ /**
+ * @todo Wrong/old documentation
+ *
+ * Creates a cast expression for the type @p name via the schema type
+ * factory @p factory. This function is used by parser when creating
+ * 'cast to' expressions, and the ConstructorFunctionsFactory, when creating
+ * constructor functions.
+ *
+ * @param targetType the type which the CastAs should cast to
+ * @param source the operand to evaluate and then cast from
+ */
+ CastAs(const Expression::Ptr &source,
+ const SequenceType::Ptr &targetType);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns a SequenceType where the ItemType is this CastAs's
+ * target type, as per targetType(), and the Cardinality is inferred from the
+ * source operand to reflect whether this CastAs always will evaluate to
+ * exactly-one or zero-or-one values.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Overridden in order to check that casting to an abstract type
+ * is not attempted.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * If the target type is the same as the source type, it is rewritten
+ * to the operand.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline ItemType::Ptr targetType() const
+ {
+ return m_targetType->itemType();
+ }
+
+ inline SequenceType::Ptr targetSequenceType() const
+ {
+ return m_targetType;
+ }
+
+ private:
+ /**
+ * Performs casting to @c xs:QName. This case is special, and is always done at compile time.
+ */
+ Expression::Ptr castToQName(const StaticContext::Ptr &context) const;
+
+ const SequenceType::Ptr m_targetType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcastingplatform.cpp b/src/xmlpatterns/expr/qcastingplatform.cpp
new file mode 100644
index 0000000..04b6349
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastingplatform.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qcastingplatform_p.h.
+ * If you need includes in this file, put them in CasttingPlatform.h, outside of the namespace.
+ */
+
+template <typename TSubClass, const bool issueError>
+Item CastingPlatform<TSubClass, issueError>::castWithCaster(const Item &sourceValue,
+ const AtomicCaster::Ptr &caster,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(sourceValue);
+ Q_ASSERT(caster);
+ Q_ASSERT(context);
+
+ const Item retval(caster->castFrom(sourceValue, context));
+
+ if(issueError)
+ {
+ if(retval.template as<AtomicValue>()->hasError())
+ {
+ issueCastError(retval, sourceValue, context);
+ return Item();
+ }
+ else
+ return retval;
+ }
+ else
+ return retval;
+}
+
+template <typename TSubClass, const bool issueError>
+Item CastingPlatform<TSubClass, issueError>::cast(const Item &sourceValue,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(sourceValue);
+ Q_ASSERT(context);
+ Q_ASSERT(targetType());
+
+ if(m_caster)
+ return castWithCaster(sourceValue, m_caster, context);
+ else
+ {
+ bool castImpossible = false;
+ const AtomicCaster::Ptr caster(locateCaster(sourceValue.type(), context, castImpossible, static_cast<const TSubClass *>(this), targetType()));
+
+ if(!issueError && castImpossible)
+ {
+ /* If we're supposed to issue an error(issueError) then this
+ * line will never be reached, because locateCaster() will in
+ * that case throw. */
+ return ValidationError::createError();
+ }
+ else
+ return castWithCaster(sourceValue, caster, context);
+ }
+}
+
+template <typename TSubClass, const bool issueError>
+bool CastingPlatform<TSubClass, issueError>::prepareCasting(const ReportContext::Ptr &context,
+ const ItemType::Ptr &sourceType)
+{
+ Q_ASSERT(sourceType);
+ Q_ASSERT(context);
+
+ if(*sourceType == *BuiltinTypes::xsAnyAtomicType ||
+ *sourceType == *BuiltinTypes::item ||
+ *sourceType == *CommonSequenceTypes::Empty ||
+ *sourceType == *BuiltinTypes::numeric)
+ return true; /* The type could not be narrowed better than xs:anyAtomicType
+ or numeric at compile time. We'll do lookup at runtime instead. */
+
+ bool castImpossible = false;
+ m_caster = locateCaster(sourceType, context, castImpossible, static_cast<const TSubClass *>(this), targetType());
+
+ return !castImpossible;
+}
+
+template <typename TSubClass, const bool issueError>
+AtomicCaster::Ptr CastingPlatform<TSubClass, issueError>::locateCaster(const ItemType::Ptr &sourceType,
+ const ReportContext::Ptr &context,
+ bool &castImpossible,
+ const SourceLocationReflection *const location,
+ const ItemType::Ptr &targetType)
+{
+ Q_ASSERT(sourceType);
+ Q_ASSERT(targetType);
+
+ const AtomicCasterLocator::Ptr locator(static_cast<AtomicType *>(
+ targetType.data())->casterLocator());
+ if(!locator)
+ {
+ if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("No casting is possible with %1 as the target type.")
+ .arg(formatType(context->namePool(), targetType)),
+ ReportContext::XPTY0004, location);
+ }
+ else
+ castImpossible = true;
+
+ return AtomicCaster::Ptr();
+ }
+
+ const AtomicCaster::Ptr caster(static_cast<const AtomicType *>(sourceType.data())->accept(locator, location));
+ if(!caster)
+ {
+ if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("It is not possible to cast from %1 to %2.")
+ .arg(formatType(context->namePool(), sourceType))
+ .arg(formatType(context->namePool(), targetType)),
+ ReportContext::XPTY0004, location);
+ }
+ else
+ castImpossible = true;
+
+ return AtomicCaster::Ptr();
+ }
+
+ return caster;
+}
+
+template <typename TSubClass, const bool issueError>
+void CastingPlatform<TSubClass, issueError>::checkTargetType(const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+
+ const ItemType::Ptr tType(targetType());
+ Q_ASSERT(tType);
+ Q_ASSERT(tType->isAtomicType());
+ const AtomicType::Ptr asAtomic(tType);
+
+ /* This catches casting to xs:NOTATION and xs:anyAtomicType. */
+ if(asAtomic->isAbstract())
+ {
+ context->error(QtXmlPatterns::tr("Casting to %1 is not possible because it "
+ "is an abstract type, and can therefore never be instantiated.")
+ .arg(formatType(context->namePool(), tType)),
+ ReportContext::XPST0080,
+ static_cast<const TSubClass*>(this));
+ }
+}
+
+template <typename TSubClass, const bool issueError>
+void CastingPlatform<TSubClass, issueError>::issueCastError(const Item &validationError,
+ const Item &sourceValue,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(validationError);
+ Q_ASSERT(context);
+ Q_ASSERT(validationError.isAtomicValue());
+ Q_ASSERT(validationError.template as<AtomicValue>()->hasError());
+
+ const ValidationError::Ptr err(validationError.template as<ValidationError>());
+ QString msg(err->message());
+
+ if(msg.isNull())
+ {
+ msg = QtXmlPatterns::tr("It's not possible to cast the value %1 of type %2 to %3")
+ .arg(formatData(sourceValue.stringValue()))
+ .arg(formatType(context->namePool(), sourceValue.type()))
+ .arg(formatType(context->namePool(), targetType()));
+ }
+ else
+ {
+ Q_ASSERT(!msg.isEmpty());
+ msg = QtXmlPatterns::tr("Failure when casting from %1 to %2: %3")
+ .arg(formatType(context->namePool(), sourceValue.type()))
+ .arg(formatType(context->namePool(), targetType()))
+ .arg(msg);
+ }
+
+ /* If m_errorCode is FORG0001, we assume our sub-classer doesn't have a
+ * special wish about error code, so then we use the error object's code.
+ */
+ context->error(msg, m_errorCode == ReportContext::FORG0001 ? err->errorCode() : m_errorCode,
+ static_cast<const TSubClass*>(this));
+}
+
diff --git a/src/xmlpatterns/expr/qcastingplatform_p.h b/src/xmlpatterns/expr/qcastingplatform_p.h
new file mode 100644
index 0000000..415003f
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastingplatform_p.h
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CastingPlatform_H
+#define Patternist_CastingPlatform_H
+
+#include "qatomiccasterlocator_p.h"
+#include "qatomiccaster_p.h"
+#include "qatomicstring_p.h"
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+#include "qschematypefactory_p.h"
+#include "qstaticcontext_p.h"
+#include "qvalidationerror_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides casting functionality for classes, such as CastAs or NumberFN, which
+ * needs to perform casting.
+ *
+ * Classes which need to perform casting can simply from this class and gain
+ * access to casting functinality wrapped in a convenient way. At the center of this
+ * class is the cast() function, which is used at runtime to perform the actual cast.
+ *
+ * The actual circumstances where casting is used, such as in the 'castable as'
+ * expression or the <tt>fn:number()</tt> function, often have other things to handle as well,
+ * error handling and cardinality checks for example. This class handles only casting
+ * and leaves the other case-specific details to the sub-class such that this class only
+ * do one thing well.
+ *
+ * This template class takes two parameters:
+ * - TSubClass This should be the class inheriting from CastingPlatform.
+ * - issueError if true, errors are issued via ReportContext, otherwise
+ * ValidationError instances are returned appropriately.
+ *
+ * The class inheriting CastingPlatform must implement the following function:
+ * @code
+ * ItemType::Ptr targetType() const
+ * @endcode
+ *
+ * that returns the type that should be cast to. The type must be an AtomicType.
+ * Typically, it is appropriate to declare this function @c inline.
+ *
+ * A sub-class calls prepareCasting() at compile time(such that CastingPlatform can attempt
+ * to lookup the proper AtomicCaster) and then it simply uses the cast() function at runtime. The
+ * function targetType() must be implemented such that CastingPlatform knows
+ * what type it shall cast to.
+ *
+ * @see ValueFactory
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ template<typename TSubClass, const bool issueError>
+ class CastingPlatform
+ {
+ protected:
+ /**
+ * @note issueCastError() depends on the default value.
+ */
+ inline CastingPlatform(const ReportContext::ErrorCode code = ReportContext::FORG0001) : m_errorCode(code)
+ {
+ }
+
+ /**
+ * Attempts to cast @p sourceValue to targetType(), and returns
+ * the created value. Remember that prepareCasting() should have been
+ * called at compile time, otherwise this function will be slow.
+ *
+ * Error reporting is done in two ways. If a cast fails because
+ * of an error in lexical representation a ValidationError is returned.
+ * If the cause of failure is that the casting combination is invalid(such as
+ * when attempting to cast @c xs:date to @c xs:integer), a ValidationError
+ * is returned if @c false was passed in the template instantiation,
+ * an error is issued via @p context.
+ *
+ * @param sourceValue the value to cast. Must be non @c null.
+ * @param context the usual ReportContext, used for error reporting.
+ * @returns the new value which was the result of the cast. If the
+ * cast failed, an ValidationError is returned.
+ */
+ Item cast(const Item &sourceValue,
+ const ReportContext::Ptr &context) const;
+
+ /**
+ * This function should be called at compiled time, it attempts to determine
+ * what AtomicCaster that should be used when casting from @p sourceType to
+ * targetType(). If that is not possible, because the @p sourceType is
+ * @c xs:anyAtomicType for instance, the AtomicCaster lookup will done at
+ * runtime on a case-per-case basis.
+ *
+ * @returns @c true if the requested casting combination is valid or might be valid.
+ * If it is guranteed to be invalid, @c false is returned.
+ */
+ bool prepareCasting(const ReportContext::Ptr &context,
+ const ItemType::Ptr &sourceType);
+
+ /**
+ * Checks that the targetType() is a valid target type for <tt>castable as</tt>
+ * and <tt>cast as</tt>. For example, that it is not abstract. If the type is
+ * invalid, an error is raised via the @p context. Note that it is assumed the type
+ * is atomic.
+ */
+ void checkTargetType(const ReportContext::Ptr &context) const;
+
+ private:
+ inline Item castWithCaster(const Item &sourceValue,
+ const AtomicCaster::Ptr &caster,
+ const ReportContext::Ptr &context) const;
+
+ /**
+ * Locates the caster for casting values of type @p sourceType to targetType(), if
+ * possible.
+ *
+ * @p castImpossible is not initialized. Initialize it to @c false.
+ */
+ static AtomicCaster::Ptr locateCaster(const ItemType::Ptr &sourceType,
+ const ReportContext::Ptr &context,
+ bool &castImpossible,
+ const SourceLocationReflection *const location,
+ const ItemType::Ptr &targetType);
+ private:
+ inline Item castWithCaster(const Item &sourceValue,
+ const AtomicCaster::Ptr &caster,
+ const DynamicContext::Ptr &context) const;
+
+
+ inline ItemType::Ptr targetType() const
+ {
+ Q_ASSERT(static_cast<const TSubClass *>(this)->targetType());
+ return static_cast<const TSubClass *>(this)->targetType();
+ }
+
+ void issueCastError(const Item &validationError,
+ const Item &sourceValue,
+ const ReportContext::Ptr &context) const;
+
+ Q_DISABLE_COPY(CastingPlatform)
+ AtomicCaster::Ptr m_caster;
+ const ReportContext::ErrorCode m_errorCode;
+ };
+
+#include "qcastingplatform.cpp"
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcollationchecker.cpp b/src/xmlpatterns/expr/qcollationchecker.cpp
new file mode 100644
index 0000000..91e4848
--- /dev/null
+++ b/src/xmlpatterns/expr/qcollationchecker.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qxpathhelper_p.h"
+
+#include "qcollationchecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CollationChecker::CollationChecker(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item CollationChecker::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item val(m_operand->evaluateSingleton(context));
+ XPathHelper::checkCollationSupport<ReportContext::FOCH0002>(val.stringValue(), context, this);
+ return val;
+}
+
+SequenceType::List CollationChecker::expectedOperandTypes() const
+{
+ SequenceType::List list;
+ list.append(CommonSequenceTypes::ExactlyOneString);
+ return list;
+}
+
+SequenceType::Ptr CollationChecker::staticType() const
+{
+ return m_operand->staticType();
+}
+
+ExpressionVisitorResult::Ptr CollationChecker::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcollationchecker_p.h b/src/xmlpatterns/expr/qcollationchecker_p.h
new file mode 100644
index 0000000..b57e8c9
--- /dev/null
+++ b/src/xmlpatterns/expr/qcollationchecker_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CollationChecker_H
+#define Patternist_CollationChecker_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Checks that its operand evaluates to a supported string collation.
+ *
+ * CollationChecker is inserted in the AST when an Expression has LastOperandIsCollation
+ * set. If the argument that CollationChecker is a string literal the CollationChecker
+ * will const-fold as usual, but otherwise will simply pipe through the value of its argument,
+ * if it's a supported collation. Otherwise it raise an error, with code ReportContext::FOCH0002.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CollationChecker : public SingleContainer
+ {
+ public:
+ CollationChecker(const Expression::Ptr &source);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * Expects exactly one string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns its operand's static type.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcombinenodes.cpp b/src/xmlpatterns/expr/qcombinenodes.cpp
new file mode 100644
index 0000000..0670faf
--- /dev/null
+++ b/src/xmlpatterns/expr/qcombinenodes.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qexceptiterator_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qintersectiterator_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qnodesort_p.h"
+#include "qunioniterator_p.h"
+
+#include "qcombinenodes_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CombineNodes::CombineNodes(const Expression::Ptr &operand1,
+ const Operator op,
+ const Expression::Ptr &operand2) : PairContainer(operand1, operand2),
+ m_operator(op)
+{
+ Q_ASSERT(op == Union ||
+ op == Except ||
+ op == Intersect);
+}
+
+Item::Iterator::Ptr CombineNodes::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr op1(m_operand1->evaluateSequence(context));
+ const Item::Iterator::Ptr op2(m_operand2->evaluateSequence(context));
+
+ switch(m_operator)
+ {
+ case Intersect:
+ return Item::Iterator::Ptr(new IntersectIterator(op1, op2));
+ case Except:
+ return Item::Iterator::Ptr(new ExceptIterator(op1, op2));
+ default:
+ {
+ Q_ASSERT(m_operator == Union);
+ return Item::Iterator::Ptr(new UnionIterator(op1, op2));
+ }
+ }
+}
+
+Item CombineNodes::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return evaluateSequence(context)->next();
+}
+
+Expression::Ptr CombineNodes::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+
+ m_operand1 = NodeSortExpression::wrapAround(m_operand1, context);
+ m_operand2 = NodeSortExpression::wrapAround(m_operand2, context);
+
+ return me;
+}
+
+bool CombineNodes::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ /* If it's the union operator, we can possibly avoid
+ * evaluating the second operand. */
+
+ if(m_operator == Union)
+ {
+ return m_operand1->evaluateEBV(context) ||
+ m_operand2->evaluateEBV(context);
+ }
+ else
+ return PairContainer::evaluateEBV(context);
+}
+
+QString CombineNodes::displayName(const Operator op)
+{
+ switch(op)
+ {
+ case Intersect:
+ return QLatin1String("intersect");
+ case Except:
+ return QLatin1String("except");
+ default:
+ {
+ Q_ASSERT(op == Union);
+ return QLatin1String("union");
+ }
+ }
+}
+
+SequenceType::Ptr CombineNodes::staticType() const
+{
+ const SequenceType::Ptr t1(m_operand1->staticType());
+ const SequenceType::Ptr t2(m_operand2->staticType());
+
+ Cardinality card;
+
+ /* Optimization: the cardinality can be better inferred for
+ * Intersect and Except, although it's not trivial code. */
+ if(m_operator == Union)
+ card = t1->cardinality() | t2->cardinality();
+ else /* Except. */
+ card = Cardinality::zeroOrMore();
+
+ return makeGenericSequenceType(t1->itemType() | t2->itemType(), card);
+}
+
+SequenceType::List CombineNodes::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+ return result;
+}
+
+CombineNodes::Operator CombineNodes::operatorID() const
+{
+ return m_operator;
+}
+
+ExpressionVisitorResult::Ptr CombineNodes::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID CombineNodes::id() const
+{
+ return IDCombineNodes;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcombinenodes_p.h b/src/xmlpatterns/expr/qcombinenodes_p.h
new file mode 100644
index 0000000..4baf196
--- /dev/null
+++ b/src/xmlpatterns/expr/qcombinenodes_p.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CombineNodes_H
+#define Patternist_CombineNodes_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's operators for combining node sequences: @c union,
+ * @c intersect and @c except.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#combining_seq">XQuery 1.0: An XML Query
+ * Language, 3.3.3 Combining QXmlNodeModelIndex Sequences</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT CombineNodes : public PairContainer
+ {
+ public:
+ enum Operator
+ {
+ Union = 1,
+ Intersect = 2,
+ Except = 4
+ };
+
+ CombineNodes(const Expression::Ptr &operand1,
+ const Operator op,
+ const Expression::Ptr &operand2);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ Operator operatorID() const;
+ virtual ID id() const;
+
+ /**
+ * Determines the string representation for operator @p op.
+ *
+ * @return "union" if @p op is Union, "intersect" if @p op
+ * is Intersect and "except" if @p op is Except.
+ */
+ static QString displayName(const Operator op);
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const Operator m_operator;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcommentconstructor.cpp b/src/xmlpatterns/expr/qcommentconstructor.cpp
new file mode 100644
index 0000000..8d7144f
--- /dev/null
+++ b/src/xmlpatterns/expr/qcommentconstructor.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qnodebuilder_p.h"
+
+#include "qcommentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CommentConstructor::CommentConstructor(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+QString CommentConstructor::evaluateContent(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ if(!item)
+ return QString();
+
+ const QString content(item.stringValue());
+
+ if(content.contains(QLatin1String("--")))
+ {
+ context->error(QtXmlPatterns::tr("A comment cannot contain %1")
+ .arg(formatData("--")),
+ ReportContext::XQDY0072, this);
+ }
+ else if(content.endsWith(QLatin1Char('-')))
+ {
+ context->error(QtXmlPatterns::tr("A comment cannot end with a %1.")
+ .arg(formatData(QLatin1Char('-'))),
+ ReportContext::XQDY0072, this);
+ }
+
+ return content;
+}
+
+Item CommentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QString content(evaluateContent(context));
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+ nodeBuilder->comment(content);
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void CommentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ const QString content(evaluateContent(context));
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ receiver->comment(content);
+}
+
+SequenceType::Ptr CommentConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneComment;
+}
+
+SequenceType::List CommentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties CommentConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+CommentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcommentconstructor_p.h b/src/xmlpatterns/expr/qcommentconstructor_p.h
new file mode 100644
index 0000000..75467ec
--- /dev/null
+++ b/src/xmlpatterns/expr/qcommentconstructor_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CommentConstructor_H
+#define Patternist_CommentConstructor_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a comment node. This covers both computed and directly constructed
+ * text nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CommentConstructor : public SingleContainer
+ {
+ public:
+ CommentConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+
+ private:
+ inline QString evaluateContent(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcomparisonplatform.cpp b/src/xmlpatterns/expr/qcomparisonplatform.cpp
new file mode 100644
index 0000000..625dd01
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomparisonplatform.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qcomparisonplatform_p.h.
+ * If you need includes in this file, put them in qcomparisonplatform_p.h, outside of the namespace.
+ */
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+bool ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+flexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const
+{
+ if(m_comparator)
+ /* The comparator was located at compile time. */
+ return compare(it1, it2, m_comparator, operatorID());
+ else
+ {
+ const AtomicComparator::Ptr cp(fetchComparator(it1.type(),
+ it2.type(),
+ context));
+
+ return cp ? compare(it1, it2, cp, operatorID()) : false;
+ }
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+AtomicComparator::ComparisonResult
+ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+detailedFlexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const
+{
+ AtomicComparator::Ptr comp;
+
+ if(m_comparator)
+ comp = m_comparator;
+ else
+ {
+ comp = fetchComparator(it1.type(),
+ it2.type(),
+ context);
+ }
+
+ Q_ASSERT_X(operatorID() == AtomicComparator::OperatorLessThanNaNLeast || operatorID() == AtomicComparator::OperatorLessThanNaNGreatest,
+ Q_FUNC_INFO, "Only OperatorLessThan is currently supported for this function.");
+ return comp->compare(it1, operatorID(), it2);
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+bool ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+compare(const Item &oand1,
+ const Item &oand2,
+ const AtomicComparator::Ptr &comp,
+ const AtomicComparator::Operator op) const
+{
+ Q_ASSERT(oand1);
+ Q_ASSERT(oand2);
+ Q_ASSERT(comp);
+
+ switch(op)
+ {
+ case AtomicComparator::OperatorEqual:
+ return comp->equals(oand1, oand2);
+ case AtomicComparator::OperatorNotEqual:
+ return !comp->equals(oand1, oand2);
+ case AtomicComparator::OperatorLessThanNaNLeast:
+ case AtomicComparator::OperatorLessThanNaNGreatest:
+ /* Fallthrough. */
+ case AtomicComparator::OperatorLessThan:
+ return comp->compare(oand1, op, oand2) == AtomicComparator::LessThan;
+ case AtomicComparator::OperatorGreaterThan:
+ return comp->compare(oand1, op, oand2) == AtomicComparator::GreaterThan;
+ case AtomicComparator::OperatorLessOrEqual:
+ {
+ const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2);
+ return ret == AtomicComparator::LessThan || ret == AtomicComparator::Equal;
+ }
+ case(AtomicComparator::OperatorGreaterOrEqual):
+ {
+ const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2);
+ return ret == AtomicComparator::GreaterThan || ret == AtomicComparator::Equal;
+ }
+ }
+
+ /* GCC unbarfer, this line should never be reached. */
+ Q_ASSERT(false);
+ return false;
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+AtomicComparator::Ptr ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+fetchComparator(const ItemType::Ptr &t1,
+ const ItemType::Ptr &t2,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(t1);
+ Q_ASSERT(t2);
+
+ if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::xsAnyAtomicType == *t2 ||
+ *BuiltinTypes::item == *t1 ||
+ *BuiltinTypes::item == *t2 ||
+ *BuiltinTypes::numeric == *t1 ||
+ *BuiltinTypes::numeric == *t2 ||
+ *CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ /* The static type of(at least) one of the operands could not
+ * be narrowed further, so we do the operator
+ * lookup at runtime.
+ */
+ return AtomicComparator::Ptr();
+ }
+
+ const AtomicComparatorLocator::Ptr locator
+ (static_cast<const AtomicType *>(t1.data())->comparatorLocator());
+
+ if(!locator)
+ {
+ if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("No comparisons can be done involving the type %1.")
+ .arg(formatType(context->namePool(), t1)),
+ errorCode, static_cast<const TSubClass *>(this)->actualReflection());
+ }
+ return AtomicComparator::Ptr();
+ }
+
+ const AtomicComparator::Ptr comp(static_cast<const AtomicType *>(t2.data())->accept(locator, operatorID(),
+ static_cast<const TSubClass *>(this)->actualReflection()));
+
+ if(comp)
+ return comp;
+ else if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("Operator %1 is not available between atomic values of type %2 and %3.")
+ .arg(formatKeyword(AtomicComparator::displayName(operatorID(),
+ comparisonType)),
+ formatType(context->namePool(), t1),
+ formatType(context->namePool(), t2)),
+ errorCode, static_cast<const TSubClass *>(this)->actualReflection());
+ }
+
+ return AtomicComparator::Ptr();
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+void ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+prepareComparison(const AtomicComparator::Ptr &c)
+{
+ m_comparator = c;
+}
+
diff --git a/src/xmlpatterns/expr/qcomparisonplatform_p.h b/src/xmlpatterns/expr/qcomparisonplatform_p.h
new file mode 100644
index 0000000..359e247
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomparisonplatform_p.h
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ComparisonPlatform_H
+#define Patternist_ComparisonPlatform_H
+
+#include "qatomiccomparators_p.h"
+#include "qitem_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qdynamiccontext_p.h"
+#include "qbuiltintypes_p.h"
+#include "qitemtype_p.h"
+#include "qpatternistlocale_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides comparison functionality for classes that compare Items,
+ * such as ValueComparison or MaxFN.
+ *
+ * Classes which need comparison functionalities should inherit from this class.
+ *
+ * The parameter of this template class is the class inheriting from ComparisonPlatform.
+ *
+ * The class inheriting ComparisonPlatform must implement the following function:
+ * @code
+ * AtomicComparator::Operator operatorID() const
+ * @endcode
+ *
+ * @author Vincent Ricard <magic@magicninja.org>
+ * @ingroup Patternist_expressions
+ */
+ template <typename TSubClass,
+ bool issueError,
+ AtomicComparator::ComparisonType comparisonType = AtomicComparator::AsValueComparison,
+ ReportContext::ErrorCode errorCode = ReportContext::XPTY0004>
+ class ComparisonPlatform
+ {
+ protected:
+ /**
+ * Makes ComparisonPlatform use the AtomicComparator @p comparator.
+ */
+ void prepareComparison(const AtomicComparator::Ptr &comparator);
+
+ /**
+ * Default constructor. Does nothing. It is implemented in order make template
+ * instantiation easier.
+ */
+ inline ComparisonPlatform()
+ {
+ }
+
+ /**
+ * Utility function for fetching the appropriate AtomicComparator
+ * for two atomic values of type @p type1 and @p type2, for the operator @p op.
+ *
+ * This function is used throughout the implementation, ranging from the ValueComparison
+ * itself, to for example the aggregate functions.
+ *
+ * @param context the ordinary ReportContext, used for issuing errors.
+ * @param type1 the type of the first operand value in a comparison for which the
+ * returned AtomicComparator is intended for
+ * @param type2 the type of the second operand value in a comparison for which the
+ * returned AtomicComparator is intended for. Whether @p type1 and @p type2 corresponds
+ * to what is the first second operand type does not have significance, the order
+ * can be arbitrary
+ */
+ AtomicComparator::Ptr
+ fetchComparator(const ItemType::Ptr &type1,
+ const ItemType::Ptr &type2,
+ const ReportContext::Ptr &context) const;
+
+ /**
+ * @short Compares @p i1 and @p i2 with operator @p op, using comparator @p
+ * comp. All input arguments must be valid, and not @c null.
+ *
+ * This is a fast, raw function which has the requirement that the
+ * caller knows what to compare and with what.
+ */
+ bool compare(const Item &i1,
+ const Item &i2,
+ const AtomicComparator::Ptr &comp,
+ const AtomicComparator::Operator op) const;
+
+ /**
+ * @short Compares @p it1 against @p it2, using comparator() and operatorID().
+ *
+ * If the comparator wasn't looked up at compile time, it will be
+ * attempted before comparing. If this fails, errors are reported via
+ * @p context.
+ */
+ bool
+ flexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const;
+
+ /**
+ * @short like flexibleCompare(), but returns the result
+ * as an AtomicComparator::Operator instead of @c bool.
+ *
+ * This is useful when it is significant how a less than comparison
+ * fails; whether the two values are equal or greater than.
+ */
+ AtomicComparator::ComparisonResult
+ detailedFlexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns the AtomicComparator that has been allocated at compile time,
+ * with prepareComparison(). If no AtomicComparator has been allocated
+ * for some reason, this function returns @c null.
+ */
+ inline const AtomicComparator::Ptr &comparator() const
+ {
+ return m_comparator;
+ }
+
+ /**
+ * Calling this function makes ComparisonPlatform use a comparator that
+ * compares strings case insensitively.
+ *
+ * @see ValueComparison::isCaseInsensitiveCompare()
+ */
+ inline void useCaseInsensitiveComparator()
+ {
+ m_comparator = AtomicComparator::Ptr(new CaseInsensitiveStringComparator());
+ }
+
+ private:
+ /**
+ * @returns the operator that is used.
+ */
+ inline AtomicComparator::Operator operatorID() const
+ {
+ Q_ASSERT(static_cast<const TSubClass *>(this)->operatorID());
+ return static_cast<const TSubClass *>(this)->operatorID();
+ }
+
+ /**
+ * The comparator that is used for comparing atomic values. The AtomicComparator
+ * that is used, depends on the static type of the operands. m_comparator can be
+ * @c null if it wasn't possible to determine what comparator to use at compile time.
+ */
+ AtomicComparator::Ptr m_comparator;
+ };
+
+#include "qcomparisonplatform.cpp"
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp b/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp
new file mode 100644
index 0000000..6eb0c0e
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "private/qxmlutils_p.h"
+
+#include "qcomputednamespaceconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ComputedNamespaceConstructor::ComputedNamespaceConstructor(const Expression::Ptr &prefix,
+ const Expression::Ptr &namespaceURI) : PairContainer(prefix, namespaceURI)
+{
+}
+
+void ComputedNamespaceConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ const Item prefixItem(m_operand1->evaluateSingleton(context));
+ const QString prefix(prefixItem ? prefixItem.stringValue() : QString());
+
+ const Item namespaceItem(m_operand2->evaluateSingleton(context));
+ const QString namespaceURI(namespaceItem ? namespaceItem.stringValue() : QString());
+
+ if(namespaceURI.isEmpty())
+ {
+ context->error(QtXmlPatterns::tr("In a namespace constructor, the value for a namespace cannot be an empty string."),
+ ReportContext::XTDE0930,
+ this);
+ }
+
+ /* One optimization could be to store a pointer to
+ * the name pool as a member in order to avoid the virtual call(s). */
+ const NamePool::Ptr np(context->namePool());
+
+ if(!prefix.isEmpty() && !QXmlUtils::isNCName(prefix))
+ {
+ context->error(QtXmlPatterns::tr("The prefix must be a valid %1, which %2 is not.")
+ .arg(formatType(np, BuiltinTypes::xsNCName),
+ formatKeyword(prefix)),
+ ReportContext::XTDE0920,
+ this);
+ }
+ const QXmlName binding(np->allocateBinding(prefix, namespaceURI));
+
+ AnyURI::toQUrl<ReportContext::XTDE0905, DynamicContext::Ptr>(namespaceURI,
+ context,
+ this);
+
+ if(binding.prefix() == StandardPrefixes::xmlns)
+ {
+ context->error(QtXmlPatterns::tr("The prefix %1 cannot be bound.")
+ .arg(formatKeyword(prefix)),
+ ReportContext::XTDE0920,
+ this);
+ }
+
+ if((binding.prefix() == StandardPrefixes::xml && binding.namespaceURI() != StandardNamespaces::xml)
+ ||
+ (binding.prefix() != StandardPrefixes::xml && binding.namespaceURI() == StandardNamespaces::xml))
+ {
+ context->error(QtXmlPatterns::tr("Only the prefix %1 can be bound to %2 and vice versa.")
+ .arg(formatKeyword(prefix), formatKeyword(namespaceURI)),
+ ReportContext::XTDE0925,
+ this);
+ }
+
+ context->outputReceiver()->namespaceBinding(binding);
+}
+
+SequenceType::Ptr ComputedNamespaceConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneAttribute;
+}
+
+SequenceType::List ComputedNamespaceConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties ComputedNamespaceConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr ComputedNamespaceConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h b/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h
new file mode 100644
index 0000000..3950052
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ComputedNamespaceConstructor_H
+#define Patternist_ComputedNamespaceConstructor_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a namespace on an element, and naturally only appears
+ * as a child of ElementConstructor.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class ComputedNamespaceConstructor : public PairContainer
+ {
+ public:
+ ComputedNamespaceConstructor(const Expression::Ptr &prefix,
+ const Expression::Ptr &namespaceURI);
+
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ExactlyOneString instance.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * The static type is exactly one attribute node. It's unclear what
+ * affects the static type has, but specifying anything else could lead
+ * to complications wrt. node order, XQTY0024. Of course, it's not
+ * conceptually correct, since a namespace node isn't an attribute
+ * node.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcontextitem.cpp b/src/xmlpatterns/expr/qcontextitem.cpp
new file mode 100644
index 0000000..caa6653
--- /dev/null
+++ b/src/xmlpatterns/expr/qcontextitem.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qcontextitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ContextItem::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->contextItem();
+}
+
+Expression::Ptr ContextItem::compress(const StaticContext::Ptr &context)
+{
+ m_itemType = context->contextItemType();
+ return EmptyContainer::compress(context);
+}
+
+Expression::Ptr ContextItem::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_itemType = context->contextItemType();
+ return EmptyContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr ContextItem::staticType() const
+{
+ /* We test m_itemType here because Patternist View calls staticType() before the typeCheck()
+ * stage. */
+ if(m_itemType)
+ return makeGenericSequenceType(m_itemType, Cardinality::exactlyOne());
+ else
+ return CommonSequenceTypes::ExactlyOneItem;
+}
+
+Expression::Properties ContextItem::properties() const
+{
+ return DisableElimination | RequiresContextItem | EvaluationCacheRedundant;
+}
+
+ExpressionVisitorResult::Ptr ContextItem::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ContextItem::id() const
+{
+ return IDContextItem;
+}
+
+ItemType::Ptr ContextItem::expectedContextItemType() const
+{
+ return BuiltinTypes::item;
+}
+
+const SourceLocationReflection *ContextItem::actualReflection() const
+{
+ if(m_expr)
+ return m_expr.data();
+ else
+ return this;
+}
+
+void ContextItem::announceFocusType(const ItemType::Ptr &type)
+{
+ Q_ASSERT(type);
+ m_itemType = type;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcontextitem_p.h b/src/xmlpatterns/expr/qcontextitem_p.h
new file mode 100644
index 0000000..e3ae81e
--- /dev/null
+++ b/src/xmlpatterns/expr/qcontextitem_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ContextItem_H
+#define Patternist_ContextItem_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the context item, the dot: <tt>.</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-context-item-expression">XML Path Language
+ * (XPath) 2.0, 3.1.4 Context Item Expression</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ContextItem : public EmptyContainer
+ {
+ public:
+ /**
+ * @p expr is possibly used for error reporting. If this context item has been
+ * created implicitly, such as for the expression <tt>fn:string()</tt>, @p expr
+ * should be passed a valid pointer to the Expression that this context
+ * item is generated for.
+ */
+ inline ContextItem(const Expression::Ptr &expr = Expression::Ptr()) : m_expr(expr)
+ {
+ }
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns always DisableElimination and RequiresContextItem
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Overridden to store a pointer to StaticContext::contextItemType().
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * Overridden to store a pointer to StaticContext::contextItemType().
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always IDContextItem
+ */
+ virtual ID id() const;
+
+ /**
+ * @returns always BuiltinTypes::item;
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual void announceFocusType(const ItemType::Ptr &type);
+
+ private:
+ ItemType::Ptr m_itemType;
+ const Expression::Ptr m_expr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcopyof.cpp b/src/xmlpatterns/expr/qcopyof.cpp
new file mode 100644
index 0000000..ddb5a2c
--- /dev/null
+++ b/src/xmlpatterns/expr/qcopyof.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qitemmappingiterator_p.h"
+
+#include "qcopyof_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CopyOf::CopyOf(const Expression::Ptr &operand,
+ const bool inheritNSS,
+ const bool preserveNSS) : SingleContainer(operand)
+ , m_inheritNamespaces(inheritNSS)
+ , m_preserveNamespaces(preserveNSS)
+ , m_settings((m_inheritNamespaces ? QAbstractXmlNodeModel::InheritNamespaces : QAbstractXmlNodeModel::NodeCopySettings()) |
+ (m_preserveNamespaces ? QAbstractXmlNodeModel::PreserveNamespaces : QAbstractXmlNodeModel::NodeCopySettings()))
+{
+}
+
+Expression::Ptr CopyOf::compress(const StaticContext::Ptr &context)
+{
+ /* We have zero effect if we have these settings. */
+ if(m_inheritNamespaces && m_preserveNamespaces)
+ return m_operand->compress(context);
+ else
+ {
+ const ItemType::Ptr t(m_operand->staticType()->itemType());
+ /* We have no effect on the empty sequence or atomic values. */
+ if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t)
+ || *t == *CommonSequenceTypes::Empty)
+ return m_operand->compress(context);
+ else
+ return SingleContainer::compress(context);
+ }
+}
+
+void CopyOf::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ /* Optimization: this completely breaks streaming. We get a call to
+ * evaluateToSequenceReceiver() but we require heap allocations by calling
+ * evaluateSequence(). */
+
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+ Item next(it->next());
+
+ while(next)
+ {
+ if(next.isNode())
+ {
+ const QXmlNodeModelIndex &asNode = next.asNode();
+ asNode.model()->copyNodeTo(asNode, receiver, m_settings);
+ }
+ else
+ receiver->item(next);
+
+ next = it->next();
+ }
+}
+
+ExpressionVisitorResult::Ptr CopyOf::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr CopyOf::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List CopyOf::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties CopyOf::properties() const
+{
+ /* We have the content of node constructors as children, but even though
+ * createCopyOf() typically avoids creating us, we can still end up with an operand
+ * that allows compression. We must always avoid that, because we don't have
+ * implementation of evaluateSequence(), and so on. */
+ return (m_operand->properties() & ~CreatesFocusForLast) | DisableElimination;
+}
+
+ItemType::Ptr CopyOf::expectedContextItemType() const
+{
+ return m_operand->expectedContextItemType();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcopyof_p.h b/src/xmlpatterns/expr/qcopyof_p.h
new file mode 100644
index 0000000..7a89b69
--- /dev/null
+++ b/src/xmlpatterns/expr/qcopyof_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CopyOf_H
+#define Patternist_CopyOf_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Does node copying in a parameterized way, in order to deal with
+ * namespace preservation/inheritance.
+ *
+ * If someone tries to call evaluateEBV(), evaluateSingleton() or
+ * evaluateSequence() on us, we will infinitely loop. But apparently
+ * that's not possible because we're always a child of ElementConstructor,
+ * currently.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CopyOf : public SingleContainer
+ {
+ public:
+ /**
+ * Creats a CopyOf where it is checked that the expression @p operand conforms
+ * to the type @p reqType.
+ */
+ CopyOf(const Expression::Ptr &operand,
+ const bool inheritNSS,
+ const bool preserveNSS);
+
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always the SequenceType passed in the constructor to this class. That is, the
+ * SequenceType that the operand must conform to.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline Item mapToItem(const Item &source,
+ const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual Properties properties() const;
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const CopyOf> ConstPtr;
+ const bool m_inheritNamespaces;
+ const bool m_preserveNamespaces;
+ const QAbstractXmlNodeModel::NodeCopySettings m_settings;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcurrentitemstore.cpp b/src/xmlpatterns/expr/qcurrentitemstore.cpp
new file mode 100644
index 0000000..0bfab8b
--- /dev/null
+++ b/src/xmlpatterns/expr/qcurrentitemstore.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcurrentitemcontext_p.h"
+#include "qstaticcurrentcontext_p.h"
+
+#include "qcurrentitemstore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CurrentItemStore::CurrentItemStore(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+DynamicContext::Ptr CurrentItemStore::createContext(const DynamicContext::Ptr &old) const
+{
+ return DynamicContext::Ptr(new CurrentItemContext(old->contextItem(), old));
+}
+
+bool CurrentItemStore::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand->evaluateEBV(createContext(context));
+}
+
+Item::Iterator::Ptr CurrentItemStore::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_operand->evaluateSequence(createContext(context));
+}
+
+Item CurrentItemStore::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand->evaluateSingleton(createContext(context));
+}
+
+SequenceType::Ptr CurrentItemStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List CurrentItemStore::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+StaticContext::Ptr CurrentItemStore::newStaticContext(const StaticContext::Ptr &context)
+{
+ /* It might be we are generated despite there is no focus. In that case
+ * an error will reported in case current() is used, but in any case we cannot
+ * crash, so use item() in case we have no focus.
+ *
+ * Such a case is when we're inside a named template, and it's invoked
+ * without focus. */
+ const ItemType::Ptr t(context->contextItemType());
+ return StaticContext::Ptr(new StaticCurrentContext(t ? t : BuiltinTypes::item, context));
+}
+
+Expression::Ptr CurrentItemStore::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(newStaticContext(context)));
+
+ if(me != this)
+ return me;
+ else
+ {
+ /* If fn:current() isn't called, there's no point in us sticking
+ * around. */
+ if(m_operand->deepProperties().testFlag(RequiresCurrentItem))
+ return me;
+ else
+ return m_operand;
+ }
+}
+
+Expression::Ptr CurrentItemStore::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ return SingleContainer::typeCheck(newStaticContext(context), reqType);
+}
+
+ExpressionVisitorResult::Ptr CurrentItemStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *CurrentItemStore::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+Expression::Properties CurrentItemStore::properties() const
+{
+ return m_operand->properties() & (RequiresFocus | IsEvaluated | DisableElimination);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcurrentitemstore_p.h b/src/xmlpatterns/expr/qcurrentitemstore_p.h
new file mode 100644
index 0000000..f7cc5d8
--- /dev/null
+++ b/src/xmlpatterns/expr/qcurrentitemstore_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CurrentItemStore_H
+#define Patternist_CurrentItemStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Creates a DynamicContext which provides the focus item for the
+ * function @c fn:current().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class CurrentItemStore : public SingleContainer
+ {
+ public:
+ CurrentItemStore(const Expression::Ptr &operand);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual Properties properties() const;
+
+ /**
+ * @returns the staticType() of its operand.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ static inline StaticContext::Ptr newStaticContext(const StaticContext::Ptr &context);
+ inline DynamicContext::Ptr createContext(const DynamicContext::Ptr &old) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qdocumentconstructor.cpp b/src/xmlpatterns/expr/qdocumentconstructor.cpp
new file mode 100644
index 0000000..9dfbe09
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentconstructor.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdocumentcontentvalidator_p.h"
+#include "qnodebuilder_p.h"
+
+#include "qdocumentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DocumentConstructor::DocumentConstructor(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+Item DocumentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI));
+
+ DocumentContentValidator validator(nodeBuilder.data(), context, ConstPtr(this));
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ validator.startDocument();
+ m_operand->evaluateToSequenceReceiver(receiverContext);
+ validator.endDocument();
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void DocumentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ DocumentContentValidator validator(receiver, context, ConstPtr(this));
+
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ validator.startDocument();
+ m_operand->evaluateToSequenceReceiver(receiverContext);
+ validator.endDocument();
+}
+
+Expression::Ptr DocumentConstructor::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_staticBaseURI = context->baseURI();
+ return SingleContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr DocumentConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneDocumentNode;
+}
+
+SequenceType::List DocumentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties DocumentConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+DocumentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qdocumentconstructor_p.h b/src/xmlpatterns/expr/qdocumentconstructor_p.h
new file mode 100644
index 0000000..8b685f9
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentconstructor_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DocumentConstructor_H
+#define Patternist_DocumentConstructor_H
+
+#include <QUrl>
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a text node. This covers both computed and directly constructed
+ * text nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class DocumentConstructor : public SingleContainer
+ {
+ public:
+ DocumentConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual Properties properties() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ private:
+ QUrl m_staticBaseURI;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp b/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp
new file mode 100644
index 0000000..75e9ae6
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpatternistlocale_p.h"
+
+#include "qdocumentcontentvalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DocumentContentValidator::
+DocumentContentValidator(QAbstractXmlReceiver *const receiver,
+ const DynamicContext::Ptr &context,
+ const Expression::ConstPtr &expr) : m_receiver(receiver)
+ , m_context(context)
+ , m_expr(expr)
+ , m_elementDepth(0)
+{
+ Q_ASSERT(receiver);
+ Q_ASSERT(m_expr);
+ Q_ASSERT(context);
+}
+
+void DocumentContentValidator::namespaceBinding(const QXmlName &nb)
+{
+ m_receiver->namespaceBinding(nb);
+}
+
+void DocumentContentValidator::startElement(const QXmlName &name)
+{
+ ++m_elementDepth;
+ m_receiver->startElement(name);
+}
+
+void DocumentContentValidator::endElement()
+{
+ Q_ASSERT(m_elementDepth > 0);
+ --m_elementDepth;
+ m_receiver->endElement();
+}
+
+void DocumentContentValidator::attribute(const QXmlName &name,
+ const QStringRef &value)
+{
+ if(m_elementDepth == 0)
+ {
+ m_context->error(QtXmlPatterns::tr("An attribute node cannot be a "
+ "child of a document node. "
+ "Therefore, the attribute %1 "
+ "is out of place.")
+ .arg(formatKeyword(m_context->namePool(), name)),
+ ReportContext::XPTY0004, m_expr.data());
+ }
+ else
+ m_receiver->attribute(name, value);
+}
+
+void DocumentContentValidator::comment(const QString &value)
+{
+ m_receiver->comment(value);
+}
+
+void DocumentContentValidator::characters(const QStringRef &value)
+{
+ m_receiver->characters(value);
+}
+
+void DocumentContentValidator::processingInstruction(const QXmlName &name,
+ const QString &value)
+{
+ m_receiver->processingInstruction(name, value);
+}
+
+void DocumentContentValidator::item(const Item &outputItem)
+{
+ /* We can't send outputItem directly to m_receiver since its item() function
+ * won't dispatch to this DocumentContentValidator, but to itself. We're not sub-classing here,
+ * we're delegating. */
+
+ if(outputItem.isNode())
+ sendAsNode(outputItem);
+ else
+ m_receiver->item(outputItem);
+}
+
+void DocumentContentValidator::startDocument()
+{
+ m_receiver->startDocument();
+}
+
+void DocumentContentValidator::endDocument()
+{
+ m_receiver->endDocument();
+}
+
+void DocumentContentValidator::atomicValue(const QVariant &value)
+{
+ Q_UNUSED(value);
+}
+
+void DocumentContentValidator::startOfSequence()
+{
+}
+
+void DocumentContentValidator::endOfSequence()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h b/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h
new file mode 100644
index 0000000..92bee3f
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DocumentContentValidator_H
+#define Patternist_DocumentContentValidator_H
+
+#include "qdynamiccontext_p.h"
+#include "qexpression_p.h"
+#include "qabstractxmlreceiver.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Receives QAbstractXmlReceiver events and validates that they are correct,
+ * before sending them on to a second QAbstractXmlReceiver.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo Escape data
+ */
+ class DocumentContentValidator : public QAbstractXmlReceiver
+ {
+ public:
+ /**
+ * DocumentContentValidator does not own @p receiver.
+ */
+ DocumentContentValidator(QAbstractXmlReceiver *const receiver,
+ const DynamicContext::Ptr &context,
+ const Expression::ConstPtr &expr);
+
+ virtual void namespaceBinding(const QXmlName &nb);
+ virtual void characters(const QStringRef &value);
+ virtual void comment(const QString &value);
+
+ virtual void startElement(const QXmlName &name);
+
+ virtual void endElement();
+
+ virtual void attribute(const QXmlName &name,
+ const QStringRef &value);
+
+ virtual void processingInstruction(const QXmlName &name,
+ const QString &value);
+
+ virtual void item(const Item &item);
+
+ virtual void startDocument();
+ virtual void endDocument();
+ virtual void atomicValue(const QVariant &value);
+ virtual void startOfSequence();
+ virtual void endOfSequence();
+
+ private:
+ QAbstractXmlReceiver *const m_receiver;
+ const DynamicContext::Ptr m_context;
+ const Expression::ConstPtr m_expr;
+ xsInteger m_elementDepth;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qdynamiccontextstore.cpp b/src/xmlpatterns/expr/qdynamiccontextstore.cpp
new file mode 100644
index 0000000..762b7d6
--- /dev/null
+++ b/src/xmlpatterns/expr/qdynamiccontextstore.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+
+#include "qdynamiccontextstore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DynamicContextStore::DynamicContextStore(const Expression::Ptr &operand,
+ const DynamicContext::Ptr &context) : SingleContainer(operand),
+ m_context(context)
+{
+ Q_ASSERT(context);
+}
+
+bool DynamicContextStore::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return m_operand->evaluateEBV(m_context);
+}
+
+Item::Iterator::Ptr DynamicContextStore::evaluateSequence(const DynamicContext::Ptr &) const
+{
+ return m_operand->evaluateSequence(m_context);
+}
+
+Item DynamicContextStore::evaluateSingleton(const DynamicContext::Ptr &) const
+{
+ return m_operand->evaluateSingleton(m_context);
+}
+
+SequenceType::Ptr DynamicContextStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List DynamicContextStore::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr DynamicContextStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *DynamicContextStore::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qdynamiccontextstore_p.h b/src/xmlpatterns/expr/qdynamiccontextstore_p.h
new file mode 100644
index 0000000..1d5d035
--- /dev/null
+++ b/src/xmlpatterns/expr/qdynamiccontextstore_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DynamicContextStore_H
+#define Patternist_DynamicContextStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Evaluates its operand with an assigned DynamicContext, not
+ * the one passed to one of the evaluation functions.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class DynamicContextStore : public SingleContainer
+ {
+ public:
+ DynamicContextStore(const Expression::Ptr &operand,
+ const DynamicContext::Ptr &context);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ /**
+ * @returns the staticType() of its operand.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ const DynamicContext::Ptr m_context;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qelementconstructor.cpp b/src/xmlpatterns/expr/qelementconstructor.cpp
new file mode 100644
index 0000000..41f7b11
--- /dev/null
+++ b/src/xmlpatterns/expr/qelementconstructor.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdelegatingnamespaceresolver_p.h"
+#include "qnamespaceconstructor_p.h"
+#include "qnodebuilder_p.h"
+#include "qoutputvalidator_p.h"
+#include "qqnamevalue_p.h"
+#include "qstaticnamespacecontext_p.h"
+
+#include "qelementconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ElementConstructor::ElementConstructor(const Expression::Ptr &op1,
+ const Expression::Ptr &op2,
+ const bool isXSLT) : PairContainer(op1, op2)
+ , m_isXSLT(isXSLT)
+{
+}
+
+Item ElementConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand1->evaluateSingleton(context));
+
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI));
+ OutputValidator validator(nodeBuilder.data(), context, this, m_isXSLT);
+
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ nodeBuilder->startElement(name.as<QNameValue>()->qName());
+ m_operand2->evaluateToSequenceReceiver(receiverContext);
+ nodeBuilder->endElement();
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void ElementConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ /* We create an OutputValidator here too. If we're serializing(a common
+ * case, unfortunately) the receiver is already validating in order to
+ * catch cases where a computed attribute constructor is followed by an
+ * element constructor, but in the cases where we're not serializing it's
+ * necessary that we validate in this step. */
+ const Item name(m_operand1->evaluateSingleton(context));
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ OutputValidator validator(receiver, context, this, m_isXSLT);
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ receiver->startElement(name.as<QNameValue>()->qName());
+ m_operand2->evaluateToSequenceReceiver(receiverContext);
+ receiver->endElement();
+}
+
+Expression::Ptr ElementConstructor::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* What does this code do? When type checking our children, our namespace
+ * bindings, which are also children of the form of NamespaceConstructor
+ * instances, must be statically in-scope for them, so find them and
+ * shuffle their bindings into the StaticContext. */
+
+ m_staticBaseURI = context->baseURI();
+
+ /* Namespace declarations changes the in-scope bindings, so let's
+ * first lookup our child NamespaceConstructors. */
+ const ID operandID = m_operand2->id();
+
+ NamespaceResolver::Bindings overrides;
+ if(operandID == IDExpressionSequence)
+ {
+ const Expression::List operands(m_operand2->operands());
+ const int len = operands.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ if(operands.at(i)->is(IDNamespaceConstructor))
+ {
+ const QXmlName &nb = operands.at(i)->as<NamespaceConstructor>()->namespaceBinding();
+ overrides.insert(nb.prefix(), nb.namespaceURI());
+ }
+ }
+ }
+
+ const NamespaceResolver::Ptr newResolver(new DelegatingNamespaceResolver(context->namespaceBindings(), overrides));
+ const StaticContext::Ptr augmented(new StaticNamespaceContext(newResolver, context));
+
+ return PairContainer::typeCheck(augmented, reqType);
+}
+
+SequenceType::Ptr ElementConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneElement;
+}
+
+SequenceType::List ElementConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneQName);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties ElementConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+ElementConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qelementconstructor_p.h b/src/xmlpatterns/expr/qelementconstructor_p.h
new file mode 100644
index 0000000..55c18a2
--- /dev/null
+++ b/src/xmlpatterns/expr/qelementconstructor_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ElementConstructor_H
+#define Patternist_ElementConstructor_H
+
+#include <QUrl>
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs an element node. This covers both computed and directly constructed
+ * element nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ElementConstructor : public PairContainer
+ {
+ public:
+ ElementConstructor(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const bool isXSLT);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:QName, and the second
+ * argument can be zero or more items.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual Properties properties() const;
+
+ private:
+ QUrl m_staticBaseURI;
+ const bool m_isXSLT;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qemptycontainer.cpp b/src/xmlpatterns/expr/qemptycontainer.cpp
new file mode 100644
index 0000000..4681fc0
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptycontainer.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QList>
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::List EmptyContainer::operands() const
+{
+ return Expression::List();
+}
+
+SequenceType::List EmptyContainer::expectedOperandTypes() const
+{
+ return SequenceType::List();
+}
+
+void EmptyContainer::setOperands(const Expression::List &)
+{
+}
+
+bool EmptyContainer::compressOperands(const StaticContext::Ptr &)
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qemptycontainer_p.h b/src/xmlpatterns/expr/qemptycontainer_p.h
new file mode 100644
index 0000000..d1eace6
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptycontainer_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_EmptyContainer_H
+#define Patternist_EmptyContainer_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has no operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT EmptyContainer : public Expression
+ {
+ public:
+ /**
+ * @returns always an empty list.
+ */
+ virtual Expression::List operands() const;
+
+ /**
+ * Does nothing, since sub-classes has no operands. Calling
+ * it makes hence no sense, and it also results in an assert crash.
+ */
+ virtual void setOperands(const Expression::List &);
+
+ protected:
+ /**
+ * @returns always @c true
+ */
+ virtual bool compressOperands(const StaticContext::Ptr &context);
+
+ /**
+ * @returns always an empty list since it has no operands.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qemptysequence.cpp b/src/xmlpatterns/expr/qemptysequence.cpp
new file mode 100644
index 0000000..66b6381
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptysequence.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonvalues_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequencetype_p.h"
+
+#include "qemptysequence_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr EmptySequence::create(const Expression *const replacementFor,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(replacementFor);
+ Q_ASSERT(context);
+
+ const Expression::Ptr retval(new EmptySequence());
+ context->wrapExpressionWith(replacementFor, retval);
+ return retval;
+}
+
+Item::Iterator::Ptr EmptySequence::evaluateSequence(const DynamicContext::Ptr &) const
+{
+ return CommonValues::emptyIterator;
+}
+
+Item EmptySequence::evaluateSingleton(const DynamicContext::Ptr &) const
+{
+ return Item();
+}
+
+void EmptySequence::evaluateToSequenceReceiver(const DynamicContext::Ptr &) const
+{
+}
+
+ItemType::Ptr EmptySequence::type() const
+{
+ return CommonSequenceTypes::Empty;
+}
+
+SequenceType::Ptr EmptySequence::staticType() const
+{
+ return CommonSequenceTypes::Empty;
+}
+
+bool EmptySequence::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return false;
+}
+
+QString EmptySequence::stringValue() const
+{
+ return QString();
+}
+
+ExpressionVisitorResult::Ptr EmptySequence::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID EmptySequence::id() const
+{
+ return IDEmptySequence;
+}
+
+Expression::Properties EmptySequence::properties() const
+{
+ return IsEvaluated;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qemptysequence_p.h b/src/xmlpatterns/expr/qemptysequence_p.h
new file mode 100644
index 0000000..d6a72a2
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptysequence_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_EmptySequence_H
+#define Patternist_EmptySequence_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of empty sequence: <tt>()</tt>.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class EmptySequence : public EmptyContainer
+ {
+ public:
+ /**
+ * @short Creates an EmptySequence that is a replacement for @p
+ * replacementFor.
+ *
+ * @see EmptySequence()
+ */
+ static Expression::Ptr create(const Expression *const replacementFor,
+ const StaticContext::Ptr &context);
+
+
+ /**
+ * @short Creates an instance of EmptySequence.
+ *
+ * @note In most cases create() should be used, since it takes care of
+ * adjusting source location annotations.
+ *
+ * @see create()
+ */
+ inline EmptySequence()
+ {
+ }
+
+ virtual QString stringValue() const;
+
+ /**
+ * @returns always an empty iterator, an instance of EmptyIterator.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+
+ /**
+ * @returns always @c null.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * Does nothing.
+ */
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &) const;
+
+ /**
+ * @returns always @c false.
+ */
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always CommonSequenceTypes::Empty
+ */
+ virtual ItemType::Ptr type() const;
+
+ /**
+ * @returns always CommonSequenceTypes::Empty
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+ virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qevaluationcache.cpp b/src/xmlpatterns/expr/qevaluationcache.cpp
new file mode 100644
index 0000000..2d1bb56
--- /dev/null
+++ b/src/xmlpatterns/expr/qevaluationcache.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qevaluationcache_p.h.
+ * If you need includes in this file, put them in qevaluationcache_p.h, outside of the namespace.
+ */
+
+template<bool IsForGlobal>
+EvaluationCache<IsForGlobal>::EvaluationCache(const Expression::Ptr &op,
+ const VariableDeclaration::Ptr &varDecl,
+ const VariableSlotID aSlot) : SingleContainer(op)
+ , m_declaration(varDecl)
+ , m_varSlot(aSlot)
+{
+ Q_ASSERT(m_declaration);
+ Q_ASSERT(m_varSlot > -1);
+}
+
+template<bool IsForGlobal>
+DynamicContext::Ptr EvaluationCache<IsForGlobal>::topFocusContext(const DynamicContext::Ptr &context)
+{
+ DynamicContext::Ptr result(context);
+
+ while(true)
+ {
+ DynamicContext::Ptr candidate(result->previousContext());
+
+ /* We want the top focus, not GenericDynamicContext. */
+ if(candidate && candidate->focusIterator())
+ result = candidate;
+ else
+ return result;
+ }
+}
+
+template<bool IsForGlobal>
+Item EvaluationCache<IsForGlobal>::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ ItemCacheCell &cell = IsForGlobal ? context->globalItemCacheCell(m_varSlot) : context->itemCacheCell(m_varSlot);
+
+ if(cell.cacheState == ItemCacheCell::Full)
+ return cell.cachedItem;
+ else
+ {
+ Q_ASSERT(cell.cacheState == ItemCacheCell::Empty);
+ cell.cachedItem = m_operand->evaluateSingleton(IsForGlobal ? topFocusContext(context) : context);
+ cell.cacheState = ItemCacheCell::Full;
+ return cell.cachedItem;
+ }
+}
+
+#if defined(Q_OS_IRIX) && defined(Q_CC_MIPS)
+/**
+ * @short Compile workaround for MIPSPro on IRIX.
+ *
+ * This function is never called.
+ *
+ * It's mere presence means the MIPSPro compiler can accept some other code below.
+ *
+ * I recommend Buddism.
+ */
+static inline Item::Iterator::Ptr workaroundIrixMIPSPro(const ItemSequenceCacheCell &cell)
+{
+ return Item::Iterator::Ptr(new ListIterator<Item, Item::List>(cell.cachedItems));
+}
+#endif
+
+template<bool IsForGlobal>
+Item::Iterator::Ptr EvaluationCache<IsForGlobal>::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ ItemSequenceCacheCell::Vector &cells = IsForGlobal ? context->globalItemSequenceCacheCells(m_varSlot) : context->itemSequenceCacheCells(m_varSlot);
+ ItemSequenceCacheCell &cell = cells[m_varSlot];
+
+
+ if(cell.inUse)
+ {
+ context->error(QtXmlPatterns::tr("Circularity detected"),
+ ReportContext::XTDE0640, this);
+ }
+
+ switch(cell.cacheState)
+ {
+ case ItemSequenceCacheCell::Full:
+ {
+ /**
+ * We don't use makeListIterator() here because the MIPSPro compiler can't handle it.
+ */
+ return Item::Iterator::Ptr(new ListIterator<Item, Item::List>(cell.cachedItems));
+ }
+ case ItemSequenceCacheCell::Empty:
+ {
+ cell.inUse = true;
+ cell.sourceIterator = m_operand->evaluateSequence(IsForGlobal ? topFocusContext(context) : context);
+ cell.cacheState = ItemSequenceCacheCell::PartiallyPopulated;
+ /* Fallthrough. */
+ }
+ case ItemSequenceCacheCell::PartiallyPopulated:
+ {
+ cell.inUse = false;
+ Q_ASSERT_X(cells.at(m_varSlot).sourceIterator, Q_FUNC_INFO,
+ "This trigger for a cache bug which hasn't yet been analyzed.");
+ return Item::Iterator::Ptr(new CachingIterator(cells, m_varSlot, IsForGlobal ? topFocusContext(context) : context));
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This path is not supposed to be run.");
+ return Item::Iterator::Ptr();
+ }
+ }
+}
+
+template<bool IsForGlobal>
+Expression::Ptr EvaluationCache<IsForGlobal>::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* It's important that we do the typeCheck() before checking for the use of local variables,
+ * because ExpressionVariableReference can reference an expression that is a local variable,
+ * so it must rewrite itself to it operand before, and it does that in EvaluationCache::typeCheck(). */
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+
+ OperandsIterator it(me, OperandsIterator::ExcludeParent);
+ Expression::Ptr next(it.next());
+
+ /* If our operand or any sub operand gets its value from a for-loop, we cannot
+ * cache it since then our cache would be filled -- but not invalidated -- on the
+ * first for-iteration. Consider this query:
+ *
+ * <tt>for $i in expr
+ * let $v := $i/p
+ * return ($v, $v)</tt>
+ *
+ * An evaluation cache is inserted for the two operands in the return clause. However,
+ * $i changes for each iteration so the cache can only be active on a per-iteration basis,
+ * it it's possible(which it isn't).
+ *
+ * This means that for some queries we don't cache what we really should, and hence evaluate
+ * in a sub-optimal way, since this DependsOnLocalVariable don't communicate whether it references
+ * a loop that affects us. The correct fix for this would be to let ForExpression reset the
+ * relevant caches only, but we don't know which ones that are. */
+ while(next)
+ {
+ if(next->has(DependsOnLocalVariable))
+ return m_operand->typeCheck(context, reqType);
+
+ next = it.next();
+ }
+
+ return me;
+}
+
+template<bool IsForGlobal>
+Expression::Ptr EvaluationCache<IsForGlobal>::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ if(m_operand->is(IDRangeVariableReference))
+ return m_operand;
+
+ if(m_declaration->usedByMany())
+ {
+ /* If it's only an atomic value an EvaluationCache is overkill. However,
+ * it's still needed for functions like fn:current-time() that must adhere to
+ * query stability. */
+ const Properties props(m_operand->properties());
+
+ if(props.testFlag(EvaluationCacheRedundant) ||
+ ((props.testFlag(IsEvaluated)) &&
+ !props.testFlag(DisableElimination) &&
+ CommonSequenceTypes::ExactlyOneAtomicType->matches(m_operand->staticType())))
+ {
+ return m_operand;
+ }
+ else
+ return me;
+ }
+ else
+ {
+ /* If we're only used once, there's no need for an EvaluationCache. */
+ return m_operand;
+ }
+}
+
+template<bool IsForGlobal>
+SequenceType::Ptr EvaluationCache<IsForGlobal>::staticType() const
+{
+ return m_operand->staticType();
+}
+
+template<bool IsForGlobal>
+SequenceType::List EvaluationCache<IsForGlobal>::expectedOperandTypes() const
+{
+ /* Remember that EvaluationCache::typeCheck() will be called from multiple locations,
+ * which potentially have different type requirements. For instance, one wants a node,
+ * and another requires atomization and casting.
+ *
+ * Returning ZeroOrMoreItems is safe here because staticType() returns the operand's type
+ * and therefore the convertors like Atomizer will be parents to us, and hence only affect
+ * the relevant path.
+ *
+ * ZeroOrMoreItems also make sense logically since we're actually only used where the
+ * variable references reference us. */
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+
+ return result;
+}
+
+template<bool IsForGlobal>
+Expression::Properties EvaluationCache<IsForGlobal>::properties() const
+{
+ /* We cannot return the operand's properties unconditionally, because some
+ * doesn't hold for this Expression.
+ *
+ * However, some of the properties must propagate through, which are the ones being OR'd here.
+ */
+ return m_operand->properties() & (DisableElimination | IsEvaluated | DisableTypingDeduction);
+}
+
+template<bool IsForGlobal>
+ExpressionVisitorResult::Ptr
+EvaluationCache<IsForGlobal>::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+template<bool IsForGlobal>
+const SourceLocationReflection *EvaluationCache<IsForGlobal>::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
diff --git a/src/xmlpatterns/expr/qevaluationcache_p.h b/src/xmlpatterns/expr/qevaluationcache_p.h
new file mode 100644
index 0000000..86aeaf8
--- /dev/null
+++ b/src/xmlpatterns/expr/qevaluationcache_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_EvaluationCache_H
+#define Patternist_EvaluationCache_H
+
+#include "qcachingiterator_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+#include "qoperandsiterator_p.h"
+#include "qsinglecontainer_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Evaluates to the same result as its operand, but ensures the
+ * operand is evaluated once even if this Expression is evaluated several
+ * times.
+ *
+ * EvaluationCache does this in a pipelined way, by delivering items from
+ * its cache, which is stored in the DynamicContext. If the cache has less
+ * items than what the caller requests, EvaluationCache continues to
+ * deliver but this time from the source, which it also populates into the
+ * cache.
+ *
+ * EvaluationCache is used as an optimization in order to avoid running
+ * expensive code paths multiple times, but also is sometimes a necessity:
+ * for instance, when objects must be unique, such as potentially in the
+ * case of node identity.
+ *
+ * EvaluationCache is in particular used for variables, whose sole purpose
+ * is to store it once(at least conceptually) and then use it in multiple
+ * places.
+ *
+ * In some cases an EvaluationCache isn't necessary. For instance, when a
+ * variable is only referenced once. In those cases EvaluationCache removes
+ * itself as an optimization; implemented in compress().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ template<bool IsForGlobal>
+ class EvaluationCache : public SingleContainer
+ {
+ public:
+ EvaluationCache(const Expression::Ptr &operand,
+ const VariableDeclaration::Ptr &varDecl,
+ const VariableSlotID slot);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ inline VariableSlotID slot() const
+ {
+ return m_varSlot;
+ }
+
+ private:
+ static DynamicContext::Ptr topFocusContext(const DynamicContext::Ptr &context);
+ const VariableDeclaration::Ptr m_declaration;
+ /**
+ * This variable must not be called m_slot. If it so, a compiler bug on
+ * HP-UX-aCC-64 is triggered in the constructor initializor. See the
+ * preprocessor output.
+ *
+ * Note that this is the cache slot, and is disjoint to any variable's
+ * regular slot.
+ */
+ const VariableSlotID m_varSlot;
+ };
+
+#include "qevaluationcache.cpp"
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpression.cpp b/src/xmlpatterns/expr/qexpression.cpp
new file mode 100644
index 0000000..7a045e8
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpression.cpp
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qemptysequence_p.h"
+#include "qliteral_p.h"
+#include "qliteralsequence_p.h"
+#include "qoperandsiterator_p.h"
+#include "qoptimizerframework_p.h"
+#include "qstaticfocuscontext_p.h"
+#include "qtypechecker_p.h"
+
+#include "qexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::~Expression()
+{
+}
+
+StaticContext::Ptr Expression::finalizeStaticContext(const StaticContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ const ItemType::Ptr focusType(newFocusType());
+ Q_ASSERT(focusType);
+ return StaticContext::Ptr(new StaticFocusContext(focusType, context));
+}
+
+Expression::Ptr Expression::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(reqType);
+ typeCheckOperands(context);
+ return TypeChecker::applyFunctionConversion(Expression::Ptr(this), reqType, context);
+}
+
+void Expression::typeCheckOperands(const StaticContext::Ptr &context)
+{
+ const Expression::List ops(operands());
+
+ /* Check if this expression has any operands at all. */
+ if(ops.isEmpty())
+ return; /* We're done, early exit. */
+
+ const SequenceType::List opTypes(expectedOperandTypes());
+ Expression::List result;
+
+ /* If we create a focus, we handle the last one specially, so avoid it in the loop. */
+ const bool createsFocus = has(CreatesFocusForLast);
+ const SequenceType::List::const_iterator typeEnd(createsFocus ? --opTypes.constEnd()
+ : opTypes.constEnd());
+ const Expression::List::const_iterator end(createsFocus ? --ops.constEnd()
+ : ops.constEnd());
+
+ SequenceType::List::const_iterator reqType(opTypes.constBegin());
+ SequenceType::Ptr t(*reqType);
+ // TODO we assign twice to t here(also below in loop) when ops.size() > 1
+
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ {
+ /* This ensures that the last expectedOperandType stays, and is
+ * used for all other operands. This is used for expressions that
+ * have an infinite amount of operands, such as the concat() function. */
+ if(reqType != typeEnd)
+ {
+ t = *reqType;
+ ++reqType;
+ }
+
+ /* Let the child & its children typecheck. */
+ result.append((*it)->typeCheck(context, t));
+ }
+
+ if(createsFocus)
+ {
+ const StaticContext::Ptr newContext(finalizeStaticContext(context));
+ result.append(ops.last()->typeCheck(newContext, opTypes.last()));
+ }
+
+ setOperands(result);
+}
+
+Expression::Ptr Expression::invokeOptimizers(const Expression::Ptr &expr,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(expr);
+
+ const OptimizationPass::List opts(expr->optimizationPasses());
+
+ if(opts.isEmpty()) /* Early exit. */
+ {
+ return expr;
+ }
+
+ const OptimizationPass::List::const_iterator passEnd(opts.constEnd());
+ const OptimizationPass::List::const_iterator end(opts.constEnd());
+ OptimizationPass::List::const_iterator passIt(opts.constBegin());
+
+ for(; passIt != passEnd; ++passIt) /* Invoke each optimization pass. */
+ {
+ const OptimizationPass::Ptr pass(*passIt); /* Alias, for readability. */
+ OptimizationPass::ExpressionMarker sourceMarker(pass->sourceExpression);
+
+ if(pass->startIdentifier && !pass->startIdentifier->matches(expr))
+ {
+ /* This pass specified a start identifier and it did
+ * not match -- let's try the next OptimizationPass. */
+ continue;
+ }
+
+ const ExpressionIdentifier::List::const_iterator idEnd(pass->operandIdentifiers.constEnd());
+ ExpressionIdentifier::List::const_iterator idIt(pass->operandIdentifiers.constBegin());
+ const Expression::List ops(expr->operands());
+ const Expression::List::const_iterator opEnd(ops.constEnd());
+ Expression::List::const_iterator opIt(ops.constBegin());
+
+ switch(pass->operandsMatchMethod)
+ {
+ case OptimizationPass::Sequential:
+ {
+ for(; opIt != opEnd; ++opIt)
+ {
+ const Expression::Ptr operand(*opIt); /* Alias, for readability. */
+ const ExpressionIdentifier::Ptr opIdentifier(*idIt); /* Alias, for readability. */
+ if(opIdentifier && !opIdentifier->matches(operand))
+ {
+ break;
+ }
+
+ ++idIt;
+ }
+
+ if(opIt == opEnd)
+ break; /* All operands matched, so this pass matched. */
+ else
+ {
+ /* The loop above did not finish which means all operands did not match.
+ Therefore, this OptimizationPass did not match -- let's try the next one. */
+ continue;
+ }
+ }
+ case OptimizationPass::AnyOrder:
+ {
+ Q_ASSERT_X(ops.count() == 2, Q_FUNC_INFO,
+ "AnyOrder is currently only supported for Expressions with two operands.");
+ if(pass->operandIdentifiers.first()->matches(ops.first()) &&
+ pass->operandIdentifiers.last()->matches(ops.last()))
+ {
+ break;
+ }
+ else if(pass->operandIdentifiers.first()->matches(ops.last()) &&
+ pass->operandIdentifiers.last()->matches(ops.first()))
+ {
+ sourceMarker.first() = 1;
+ sourceMarker[1] = 0;
+ break; /* This pass matched. */
+ }
+ else
+ continue; /* This pass didn't match, let's loop through the next pass. */
+ }
+ }
+
+ /* Figure out the source Expression, if any. */
+ Expression::List operands;
+ Expression::Ptr sourceExpr;
+
+ if(!sourceMarker.isEmpty())
+ {
+ const OptimizationPass::ExpressionMarker::const_iterator mEnd(sourceMarker.constEnd());
+ OptimizationPass::ExpressionMarker::const_iterator mIt(sourceMarker.constBegin());
+ sourceExpr = expr;
+
+ for(; mIt != mEnd; ++mIt)
+ {
+ Q_ASSERT(*mIt >= 0);
+ sourceExpr = sourceExpr->operands().at(*mIt);
+ }
+
+ operands.append(sourceExpr);
+ }
+
+ if(operands.isEmpty())
+ {
+ Q_ASSERT(pass->resultCreator);
+ return pass->resultCreator->create(Expression::List(), context, expr.data())->compress(context);
+ }
+ else if(pass->resultCreator)
+ return pass->resultCreator->create(operands, context, expr.data())->compress(context);
+ else
+ {
+ return sourceExpr;
+ }
+ }
+
+ return expr;
+}
+
+Expression::Ptr Expression::compress(const StaticContext::Ptr &context)
+{
+ if(!compressOperands(context))
+ {
+ /* At least one of the operands cannot be evaluated at compile, so
+ * 'this' Expression cannot const fold. */
+ return invokeOptimizers(Expression::Ptr(this), context);
+ }
+
+ Expression::Ptr retval;
+
+ if(hasDependency(DisableElimination))
+ retval = Expression::Ptr(this);
+ else
+ retval = constantPropagate(context);
+
+ return invokeOptimizers(retval, context);
+}
+
+Expression::Ptr Expression::constantPropagate(const StaticContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+
+ /* Optimization: We rewrite literals to literals here, which is pointless.
+ * Maybe we should have a property which says "doesn't disable elimination
+ * but don't eliminate me." */
+ if(staticType()->cardinality().allowsMany())
+ {
+ Item::Iterator::Ptr it(evaluateSequence(context->dynamicContext()));
+ Item::List result;
+ Item item(it->next());
+
+ while(item)
+ {
+ result.append(item);
+ item = it->next();
+ }
+
+ switch(result.count())
+ {
+ case 0:
+ return EmptySequence::create(this, context);
+ case 1:
+ return rewrite(Expression::Ptr(new Literal(result.first())), context);
+ default:
+ return rewrite(Expression::Ptr(new LiteralSequence(result)), context);
+ }
+ }
+ else
+ {
+ const Item item(evaluateSingleton(context->dynamicContext()));
+
+ if(item)
+ return rewrite(Expression::Ptr(new Literal(item)), context);
+ else
+ return EmptySequence::create(this, context);
+ }
+}
+
+Item::Iterator::Ptr Expression::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item item(evaluateSingleton(context));
+
+ if(item)
+ return makeSingletonIterator(item);
+ else
+ return CommonValues::emptyIterator;
+}
+
+Item Expression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return Boolean::fromValue(evaluateEBV(context));
+}
+
+bool Expression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return Boolean::evaluateEBV(evaluateSequence(context), context);
+}
+
+void Expression::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+ const Item::Iterator::Ptr it(evaluateSequence(context));
+ Item next(it->next());
+
+ while(next)
+ {
+ receiver->item(next);
+ next = it->next();
+ }
+}
+
+ItemType::Ptr Expression::expectedContextItemType() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "expectedContextItemType() must be overridden when RequiresContextItem is set.");
+ return ItemType::Ptr();
+}
+
+Expression::Properties Expression::properties() const
+{
+ return Properties();
+}
+
+Expression::Properties Expression::dependencies() const
+{
+ OperandsIterator it(Ptr(const_cast<Expression *>(this)), OperandsIterator::ExcludeParent);
+ Expression::Ptr next(it.next());
+
+ Properties dependencies(properties());
+
+ while(next)
+ {
+ dependencies |= next->dependencies();
+ next = it.next();
+ }
+
+ return dependencies & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+void Expression::announceFocusType(const ItemType::Ptr &itemType)
+{
+ const Expression::List ops(operands());
+ const int len = ops.count();
+
+ for(int i = 0; i < len; ++i)
+ ops.at(i)->announceFocusType(itemType);
+}
+
+Expression::Properties Expression::deepProperties() const
+{
+ Properties props(properties());
+ const Expression::List ops(operands());
+ const int len = ops.count();
+
+ for(int i = 0; i < len; ++i)
+ props |= ops.at(i)->deepProperties();
+
+ return props;
+}
+
+Expression::ID Expression::id() const
+{
+ return IDIgnorableExpression;
+}
+
+OptimizationPass::List Expression::optimizationPasses() const
+{
+ return OptimizationPass::List();
+}
+
+ItemType::Ptr Expression::newFocusType() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "This function must be overridden when CreatesFocusForLast is set.");
+ return ItemType::Ptr();
+}
+
+const SourceLocationReflection *Expression::actualReflection() const
+{
+ return this;
+}
+
+QString Expression::description() const
+{
+ return QString::fromLatin1("Expression, id: %1").arg(QString::number(id()));
+}
+
+PatternPriority Expression::patternPriority() const
+{
+ return 0.5;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexpression_p.h b/src/xmlpatterns/expr/qexpression_p.h
new file mode 100644
index 0000000..8bf37df
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpression_p.h
@@ -0,0 +1,909 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Expression_H
+#define Patternist_Expression_H
+
+#include <QFlags>
+#include <QSharedData>
+
+#include "qcppcastinghelper_p.h"
+#include "qdebug_p.h"
+#include "qdynamiccontext_p.h"
+#include "qexpressiondispatch_p.h"
+#include "qitem_p.h"
+#include "qsequencetype_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qstaticcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QList;
+template<typename T> class QVector;
+
+namespace QPatternist
+{
+ template<typename T, typename ListType> class ListIterator;
+ class OptimizationPass;
+
+ /**
+ * @short Base class for all AST nodes in an XPath/XQuery/XSL-T expression.
+ *
+ * @section ExpressionCreation Expression Compilation
+ *
+ * @subsection ExpressionCreationParser The process of creating an Expression
+ *
+ * The initial step of creating an internal representation(in some circles
+ * called an IR tree) of the XPath string follows classic compiler design: a scanner
+ * is invoked, resulting in tokens, which sub-sequently are consumed by a parser
+ * which groups the tokens into rules, resulting in the creation of
+ * Abstract Syntax Tree(AST) nodes that are arranged in a hierarchical structure
+ * similar to the EBNF.
+ *
+ * More specifically, ExpressionFactory::createExpression() is called with a
+ * pointer to a static context, and the string for the expression. This is subsequently
+ * tokenized by a Flex scanner. Mistakes detected at this stage is syntax
+ * errors, as well as a few semantical errors. Syntax errors can be divided
+ * in two types:
+ *
+ * - The scanner detects it. An example is the expression "23Eb3" which
+ * is not a valid number literal, or "1prefix:my-element" which is not a
+ * valid QName.
+ * - The parser detects it. This means a syntax error at a
+ * higher level, that a group of tokens couldn't be reduced to a
+ * rule(expression). An example is the expression "if(a = b) 'match' else
+ * 'no match'"; the tokenizer would handle it fine, but the parser would
+ * fail because the tokens could not be reduced to a rule due to the token
+ * for the "then" word was missing.
+ *
+ * Apart from the syntax errors, the actions in the parser also detects
+ * errors when creating the corresponding expressions. This is for example
+ * that no namespace binding for a prefix could be found, or that a function
+ * call was used which no function implementation could be found for.
+ *
+ * When the parser has finished, the result is an AST. That is, a
+ * hierarchical structure consisting of Expression sub-classes. The
+ * individual expressions haven't at this point done anything beyond
+ * receiving their child-expressions(if any), and hence reminds of a
+ * "construction scaffold". In other words, a tree for the expression
+ * <tt>'string' + 1 and xs:date('2001-03-13')</tt> could have been created, even if
+ * that expression contains errors(one can't add a xs:integer to a xs:string,
+ * and the Effective %Boolean Value cannot be extracted for date types).
+ *
+ * @subsection ExpressionCreationTypeChecking Type Checking
+ *
+ * After the AST creation, ExpressionFactory::createExpression continues with
+ * calling the AST node(which is an Expression instance)'s typeCheck()
+ * function. This step ensures that the static types of the operands matches
+ * the operators, and in the cases where it doesn't, modifies the AST such
+ * that the necessary conversions are done -- if possible, otherwise the
+ * result is a type error.
+ *
+ *
+ * This step corresponds roughly to what <a
+ * href="http://www.w3.org/TR/xpath20/#id-static-analysis">2.2.3.1 Static Analysis Phase</a>
+ * labels operation tree normalization; step SQ5.
+ *
+ * @subsection ExpressionCreationCompression Compressing -- Optimization and Fixup
+ *
+ * The last step is calling compress(). This function is not called
+ * 'optimize', 'simplify' or the like, because although it performs all
+ * optimization, it also involves mandatory stages.
+ *
+ * One such is const folding, which while being an efficient optimization,
+ * also is a necessity for many XSL-T constructs. Another important step is
+ * that functions which had an evaluation dependency on the static context(as
+ * opposed to the dynamic) performs their "fixup".
+ *
+ * In other words, this stage potentially performs AST re-writes. For example,
+ * the expression <tt>3 + 3, concat('foo', '-', 'bar'), true() and false()</tt> would
+ * result in an AST corresponding to <tt>6, 'foo-bar', false()</tt>. This process
+ * is done backwards; each expression asks its operands to compress before it
+ * performs its own compression(and so forth, until the root expression's call
+ * returns to the caller).
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-errors-and-opt">XML Path Language
+ * (XPath) 2.0, 2.3.4 Errors and Optimization</a>
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-expression-processing">XML Path
+ * Language (XPath) 2.0, 2.2.3 Expression Processing</a>
+ * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a Tokenizer
+ * for XPath or XQuery</a>
+ * @see ExpressionFactory
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT Expression : public QSharedData
+ , public CppCastingHelper<Expression>
+ , public SourceLocationReflection
+ {
+ public:
+ /**
+ * @short A smart pointer wrapping mutable Expression instances.
+ */
+ typedef QExplicitlySharedDataPointer<Expression> Ptr;
+
+ /**
+ * @short A smart pointer wrapping @c const Expression instances.
+ */
+ typedef QExplicitlySharedDataPointer<const Expression> ConstPtr;
+
+ /**
+ * A list of Expression instances, each wrapped in a smart pointer.
+ */
+ typedef QList<Expression::Ptr> List;
+
+ /**
+ * A vector of Expression instances, each wrapped in a smart pointer.
+ */
+ typedef QVector<Expression::Ptr> Vector;
+
+ typedef QT_PREPEND_NAMESPACE(QAbstractXmlForwardIterator<Expression::Ptr>)
+ QAbstractXmlForwardIterator;
+
+ /**
+ * Enum flags describing the characteristics of the expression.
+ *
+ * @see Expression::properties()
+ */
+ enum Property
+ {
+ /**
+ * This flag applies for functions, and results in the expression <tt>.</tt>
+ * being appended to its operands if its operand count is lower than the
+ * maximum amount of arguments.
+ *
+ * In effect, it result in a modification of the function's arguments to have
+ * appended the context item.
+ *
+ * One function which has this property is <tt>fn:number()</tt>.
+ *
+ * @see ContextItem
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 1.3 Function Signatures and Descriptions</a>
+ */
+ UseContextItem = 1,
+
+ /**
+ * Disables compression(evaluation at compile time), such that the
+ * Expression isn't const-folded, but ensured to be run at runtime. The
+ * operands are still attempted to be compressed, unless
+ * they override compression as well.
+ *
+ * @see compress()
+ */
+ DisableElimination = 1 << 1,
+
+ /**
+ * Signals that the expression is already evaluated and can be considered
+ * a constant value.
+ * For example, atomic values return this flag in their
+ * implementations of the properties() functions.
+ *
+ * @see isEvaluated()
+ */
+ IsEvaluated = 1 << 2,
+
+ /**
+ * Signals that the expression cannot be optimized away by judging
+ * its static type.
+ *
+ * This is currently used for properly handling the @c none type, in
+ * the <tt>fn:error()</tt> function. In type operations, the none type doesn't show
+ * up and that can make expressions, such as InstanceOf, believe
+ * it is safe to const fold, while it in fact is not.
+ */
+ DisableTypingDeduction = 1 << 3,
+
+ /**
+ * This property affects the static type -- staticType() -- of an expression. It
+ * is implemented in FunctionCall::staticType() and therefore only work for FunctionCall
+ * sub-classes and when that function is not re-implemented in an inhibiting way.
+ *
+ * When set, the cardinality of the static type is zero if the Expression's first
+ * operand allows an empty sequence, otherwise it is the cardinality of the Expression's
+ * static type modulo Cardinality::empty(). This is used for specifying proper static
+ * type inference for functions that have "If $arg is the empty sequence,
+ * the empty sequence is returned." However, before setting this property one
+ * must be aware that no other conditions can lead to the empty sequence, since
+ * otherwise the static type would be wrong.
+ */
+ EmptynessFollowsChild = 1 << 4,
+
+ /**
+ * This is similar to EmptynessFollowsChild, and also implemented in FunctionCall.
+ * When set, it makes FunctionCall::typeCheck() rewrite itself into an empty sequence
+ * if the first operand is the empty sequence.
+ *
+ * This property is often used together with EmptynessFollowsChild.
+ */
+ RewriteToEmptyOnEmpty = 1 << 5,
+
+ /**
+ * When set, it signals that the focus cannot be undefined. For example,
+ * the <tt>fn:position()</tt> function extracts information from the focus. Setting
+ * this flag ensures type checking is carried out appropriately.
+ *
+ * However, setting RequiresFocus does not imply this Expression requires the context
+ * item to be defined. It only means the focus, of somekind, needs to be defined.
+ *
+ * @see RequiresContextItem
+ */
+ RequiresFocus = 1 << 6,
+
+ /**
+ * An Expression with this Property set, signals that it only affects
+ * the order of its return value.
+ */
+ AffectsOrderOnly = 1 << 7,
+
+ /**
+ * When set, signals that the context item, must be defined for this Expression. When
+ * setting this property, expectedContextItemType() must be re-implemented.
+ *
+ * Setting this property also sets RequiresFocus.
+ *
+ * @see DynamicContext::contextItem()
+ */
+ RequiresContextItem = (1 << 8) | RequiresFocus,
+
+ /**
+ * When set, signals that this expression creates a focus for its last operand.
+ * When set, newFocusType() must be overridden to return the static type
+ * of the context item.
+ *
+ * @see announceFocusType()
+ * @see newFocusType()
+ */
+ CreatesFocusForLast = 1 << 9,
+
+ /**
+ * Signals that the last operand is a collation argument. This ensures
+ * that the necessary code is generated for checking that the collation
+ * is supported.
+ *
+ * This only applies to sub-classes of FunctionCall.
+ */
+ LastOperandIsCollation = 1 << 10,
+
+ /**
+ * When set, the Expression depends on local variables such as
+ * those found in @c for expressions. However, this does not
+ * include let bindings.
+ */
+ DependsOnLocalVariable = (1 << 11) | DisableElimination,
+
+ /**
+ * When set, it signals that the Expression does not need
+ * an evaluation cache, despite what other flags might imply.
+ */
+ EvaluationCacheRedundant = (1 << 12),
+
+ /**
+ * Signals that the Expression constructs nodes, either directly
+ * or computationally. For example, AttributeConstructor has this property
+ * set.
+ *
+ * Since node constructors constructs nodes which have node
+ * identities, node constructors are considered creative on
+ * evaluation.
+ */
+ IsNodeConstructor = 1 << 13,
+
+ /**
+ * Whether this expression requires the current item, as returned
+ * from @c fn:current().
+ *
+ * CurrentFN uses this flag.
+ */
+ RequiresCurrentItem = 1 << 14
+ };
+
+ /**
+ * A QFlags template for type-safe handling of ExpressionProperty values. If
+ * Expression::Property flags needs to be stored in a class, declared the variable
+ * to be of type Expression::Properties.
+ *
+ * @see QFlags
+ */
+ typedef QFlags<Property> Properties;
+
+ /**
+ * Enumerators that identifies Expression sub-classes.
+ *
+ * @see id()
+ */
+ enum ID
+ {
+ /**
+ * Identifies Boolean.
+ */
+ IDBooleanValue = 1,
+
+ /**
+ * Identifies CountFN.
+ */
+ IDCountFN,
+
+ /**
+ * Identifies EmptyFN.
+ */
+ IDEmptyFN,
+
+ /**
+ * Identifies ExistsFN.
+ */
+ IDExistsFN,
+
+ /**
+ * Identifies ExpressionSequence and LiteralSequence.
+ */
+ IDExpressionSequence,
+
+ /**
+ * Identifies GeneralComparison.
+ */
+ IDGeneralComparison,
+
+ /**
+ * Identifies IfThenClause.
+ */
+ IDIfThenClause,
+
+ /**
+ * Identifies nothing in particular. The default implementation
+ * of id() returns this, which is suitable for Expression instances
+ * which never needs to be identified in this aspect.
+ */
+ IDIgnorableExpression,
+
+ /**
+ * Identifies Integer.
+ */
+ IDIntegerValue,
+
+ /**
+ * Identifies PositionFN.
+ */
+ IDPositionFN,
+
+ /**
+ * Identifies AtomicString, AnyURI, and UntypedAtomic.
+ */
+ IDStringValue,
+
+ /**
+ * Identifies ValueComparison.
+ */
+ IDValueComparison,
+
+ /**
+ * Identifies VariableReference.
+ */
+ IDRangeVariableReference,
+
+ /**
+ * Identifies ContextItem.
+ */
+ IDContextItem,
+
+ /**
+ * Identifies UserFunctionCallsite.
+ */
+ IDUserFunctionCallsite,
+
+ /**
+ * Identifies ExpressionVariableReference.
+ */
+ IDExpressionVariableReference,
+
+ /**
+ * Identifies ExpressionVariableReference.
+ */
+ IDAttributeConstructor,
+
+ /**
+ * Identifies UpperCaseFN.
+ */
+ IDUpperCaseFN,
+
+ /**
+ * Identifies LowerCaseFN.
+ */
+ IDLowerCaseFN,
+
+ /**
+ * Identifies FirstItemPredicate.
+ */
+ IDFirstItemPredicate,
+ IDEmptySequence,
+ IDReturnOrderBy,
+ IDLetClause,
+ IDForClause,
+ IDPath,
+ IDNamespaceConstructor,
+ IDArgumentReference,
+ IDGenericPredicate,
+ IDAxisStep,
+
+ /**
+ * A literal which is either @c xs:float or
+ * @c xs:double.
+ */
+ IDFloat,
+
+ IDCombineNodes,
+ IDUnresolvedVariableReference,
+ IDCardinalityVerifier
+ };
+
+ inline Expression()
+ {
+ }
+ virtual ~Expression();
+
+ /**
+ * Evaluate this Expression by iterating over it. This is a central function
+ * for evaluating expressions.
+ *
+ * Expressions must always always return a valid QAbstractXmlForwardIterator and may
+ * never return 0. If an empty result is of interest to be returned, the
+ * EmptyIterator should be returned.
+ *
+ * The default implementation returns a SingletonIterator over the
+ * item returned from evaluateSingleton().
+ *
+ * @note This function may raise an exception when calling, not only
+ * when QAbstractXmlForwardIterator::next() is called on the return value. This is because
+ * in some cases evaluateSingleton() is called directly.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @todo Docs
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Determines the Effective %Boolean Value of the expression.
+ *
+ * The Effective %Boolean Value of a value is not necessarily the same
+ * as converting the value to a new value of type xs:boolean.
+ *
+ * Note that this function cannot return the empty sequence,
+ * evaluateSingleton() must be overridden in order to be able to do
+ * that.
+ *
+ * The default implementation results in a type error. Hence, this function
+ * must be overridden if such behavior is not of interest.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-ebv">XML Path Language (XPath) 2.0,
+ * 2.4.3 Effective Boolean Value</a>
+ */
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Evaluates this Expression by sending its output to DynamicContext::outputReceiver().
+ */
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns the expression's child expressions. For example, a function's
+ * arguments is returned here.
+ *
+ * If this Expression has no operands, an empty list should be returned.
+ */
+ virtual Expression::List operands() const = 0;
+
+ virtual void setOperands(const Expression::List &operands) = 0;
+
+ /**
+ * @returns the static type of this Expression. For example, an 'and' expression
+ * have as static type xs:boolean
+ */
+ virtual SequenceType::Ptr staticType() const = 0;
+
+ /**
+ * Returns a list of Sequence Types, describing the type of each of the
+ * expression's operands. Hence, this function has a relationship to
+ * the operands() function:
+ *
+ * - The lengths of the lists returned by expectedOperandTypes()
+ * and operands() should always be equal in length, since one
+ * cannot describe the type of a non-existent operand(and all
+ * operands must have type information).
+ * - A significant difference between the two functions is that while
+ * the type of objects in the list returned by operands() may vary
+ * between compilations/static context, simply because the particular
+ * Expression is part of different XPath expressions, the
+ * types in the list returned by expectedOperandTypes is always the same
+ * since the function/operator signature never changes.
+ *
+ * This function should not be confused with staticType(),
+ * which returns the static type of the expression itself, not its operands. The
+ * function call is an expression where this is clear: the type of the return
+ * value is not the same as the arguments' types. The static type of the
+ * operands supplied to the expression can be determined via the staticType()
+ * function of the instances returned by operands().
+ *
+ * If the expression has no operands, an empty list should be returned.
+ */
+ virtual SequenceType::List expectedOperandTypes() const = 0;
+
+ /**
+ * This implementation guarantees to never rewrite away this Expression, but
+ * at most rewrite it as a child of another expression(that presumably have a
+ * type checking role). It is therefore always safe to override this
+ * function and call this implementation and not worry about that this Expression
+ * becomes deleted.
+ *
+ * Many Expressions override typeCheck() and performs optimizations, as opposed
+ * to doing it in the compress() stage. This is due to that the design
+ * of those Expressions often are tied to that certain simplifications
+ * are done at the typeCheck() stage of the compilation process or that
+ * it in some other way is related to what the typeCheck() do. Also, the earlier
+ * the AST can be simplified, the better the chances are for subsequent
+ * optimizations.
+ *
+ * It is important that the super class's typeCheck() is called before doing
+ * any custom type checking, since the call can change the children(notably,
+ * the childrens' static types). For example, if the Expression, MyExpression
+ * in the example, does not match the required type, typeCheck returns the Expression
+ * wrapped in for example ItemVerifier, CardinalityVerifier, or both.
+ *
+ * typeCheck() may be called many times. typeCheck() must either raise an error
+ * if this Expression is an invalid expression. Thus, it is guaranteed that an Expression
+ * is valid after typeCheck() is called.
+ *
+ * @param context supplies information, such as namespace bindings and
+ * available function signatures, that can be needed at compilation time. @p context is
+ * guaranteed by the caller to never null.
+ * @param reqType the static type that this Expression must match when evaluated. @p reqType is
+ * guaranteed by the caller to never null.
+ * @returns an Expression that can be this Expression, or another expression,
+ * which somehow is necessary for making this Expression conforming to
+ * @p reqType
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * compress() is the last stage performs in compiling an expression, done after
+ * the initial AST build and calling typeCheck(). compress() performs crucial
+ * simplifications, either by having drastic performance implications or that
+ * some expressions depend on it for proper behavior.
+ *
+ * The default implementation performs a sparse conditional constant
+ * propagation. In short, a recursive process is performed in the AST
+ * which examines if the Expression's operands are constant values, and if so,
+ * performs a const fold(AST rewrite) into the result of evaluating the expression
+ * in question. This default behavior can be disabled by letting properties() return
+ * DisableElimination.
+ *
+ * This compress() stage can be relative effective due to the design of XPath, in
+ * part because intrinsic functions are heavily used. Many Expressions override compress()
+ * and do optimizations specific to what they do. Also, many Expressions performs
+ * optimizations in their typeCheck().
+ *
+ * @param context the static context. Supplies compile time information, and is
+ * the channel for communicating error messages.
+ * @see <a href="http://en.wikipedia.org/wiki/Sparse_conditional_constant_propagation">Wikipedia,
+ * the free encyclopedia, Sparse conditional constant propagation</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Intrinsic_function">Wikipedia,
+ * the free encyclopedia, Intrinsic function</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Compiler_optimization">Wikipedia, the
+ * free encyclopedia, Compiler optimization</a>
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns a bitwise OR'd value of properties, describing the
+ * characteristics of the expression. These properties affects how
+ * this Expression is treated in for example type checking stages.
+ *
+ * The default implementation returns 0. Override and let the function return
+ * a different value, if that's of interest.
+ *
+ * An important decision when re-implementing properties() is whether
+ * to OR in the properties() of ones operands. For instance, if an
+ * operand has RequiresFocus set, that flag nost likely applies to the
+ * apparent as well, since it depends on its operand.
+ *
+ * @see deepProperties()
+ * @returns Expression::None, meaning no special properties
+ */
+ virtual Properties properties() const;
+
+ /**
+ * Recursively computes through all descendants until a Property
+ * is encount
+ */
+ virtual Properties dependencies() const;
+
+ /**
+ * @short Computes the union of properties for this Expression and all
+ * its descending children.
+ *
+ * @see properties()
+ */
+ Properties deepProperties() const;
+
+ /**
+ * This function is a utility function, which performs bitwise logic
+ * on properties() in order to find out whether the Expression::IsEvaluated
+ * flag is set.
+ *
+ * @note Do not attempt to re-implement this function. Instead, return the
+ * IsEvaluated flag by re-implementing the properties() function.
+ */
+ inline bool isEvaluated() const;
+
+ /**
+ * This function is a utility function, syntactic sugar for determining
+ * whether this Expression is @p id. For example, calling <tt>is(IDIfThenClause)</tt>
+ * is equivalent to <tt>id() == IDIfThenClause</tt>
+ *
+ * @note Do not attempt to re-implement this function. Instead, return the
+ * appropriate flag in the virtual id() function.
+ */
+ inline bool is(const ID id) const;
+
+ /**
+ * Determines whether this Expression has Property @p prop set.
+ *
+ * Calling <tt>expr->has(MyProperty)</tt> is semantically equivalent
+ * to <tt>expr->properties().testFlag(MyProperty)</tt>. In
+ * other words, has(), as well as is(), provides syntacti sugar
+ * and makes code more readable.
+ *
+ * @note Do not attempt to re-implement this function. Instead, return
+ * the appropriate flag by re-implementing the properties() function.
+ */
+ inline bool has(const Property prop) const;
+
+ inline bool hasDependency(const Property prop) const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const = 0;
+
+ /**
+ * This property, which has no setter, returns an enum value that uniquely identifies
+ * this Expression. Patternist makes no use of C++'s dynamic_cast feature, but uses this
+ * polymorphic function instead.
+ *
+ * @returns always IgnorableExpression.
+ */
+ virtual ID id() const;
+
+ /**
+ * Returns the OptimizationPasses that applies for this Expression. The
+ * default implementation returns an empty list. Sub-classes can re-implement
+ * this function and return actual OptimizationPasses.
+ *
+ * @returns always an empty list.
+ */
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ /**
+ * Returns the required type the context item must be an instance of.
+ *
+ * If this Expression requires a focus, meaning its properties()
+ * function returns RequiresContextItem,
+ * it must return a type from this function. If any type is ok, BuiltinTypes::item should be
+ * returned.
+ *
+ * In other words, this function must only be re-implemented if the focus is used. The default
+ * implementation performs an assert crash.
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ /**
+ * If an Expression creates a focus because it has set the property CreatesFocusForLast,
+ * it should override this function and make it return the ItemType that
+ * the context item in the focus has.
+ *
+ * @returns never @c null.
+ * @see announceFocusType()
+ */
+ virtual ItemType::Ptr newFocusType() const;
+
+ /**
+ * @short Returns @c this.
+ */
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ /**
+ * Reimplementation of SourceLocationReflection::description().
+ */
+ virtual QString description() const;
+
+ /**
+ * When this function is called, it signals that the parent will create
+ * a focus of type @p itemType.
+ *
+ * This type can also be retrieved through StaticContext::contextItemType()
+ * when inside typeCheck(), but in some cases this is too late. For
+ * instance, a parent needs to have the static type of its child
+ * properly reported before it calls its typeCheck()(and the child's
+ * type is inferred from the focus).
+ *
+ * The default implementation delegates the call on to the children.
+ *
+ * This function may be called at arbitrary times, in arbitrary
+ * amounts.
+ *
+ * If the AST node overriding this call has children, it should be
+ * considered whether the default implementation should be called, such
+ * that they type is announced to them too.
+ *
+ * The caller guarantees that @p itemType is not @c null.
+ */
+ virtual void announceFocusType(const ItemType::Ptr &itemType);
+
+ /**
+ * This function take the two Expression pointers @p old and @p New, and
+ * in a safe way, by handling reference counting and being aware of whether
+ * the two pointers actually are different, switches the two. When compiling
+ * in debug mode, informative debug messages are printed.
+ *
+ * This function is conceptually similar to Qt's qSwap(), but has
+ * debugging functionality and also handles source locations.
+ */
+ static inline void rewrite(Expression::Ptr &old,
+ const Expression::Ptr &New,
+ const StaticContext::Ptr &context);
+
+ /**
+ * @short Rewrites this Expression to @p to, and return @p to.
+ *
+ * Source location annotations are adjusted appropriately.
+ */
+ inline const Expression::Ptr &rewrite(const Expression::Ptr &to,
+ const StaticContext::Ptr &context) const;
+
+ /**
+ * By default 0.5 is returned.
+ */
+ virtual PatternPriority patternPriority() const;
+
+ protected:
+
+ /**
+ * @returns @c true if all operands are constant values of somekind, and are already
+ * evaluated. A string literal, is a typical example.
+ */
+ virtual bool compressOperands(const StaticContext::Ptr &) = 0;
+
+ void typeCheckOperands(const StaticContext::Ptr &context);
+
+ private:
+ static Expression::Ptr invokeOptimizers(const Expression::Ptr &expr,
+ const StaticContext::Ptr &context);
+ /**
+ * @return a StaticContext that has adopted the context item type properly
+ * for this Expression.
+ */
+ inline StaticContext::Ptr finalizeStaticContext(const StaticContext::Ptr &context) const;
+
+ /**
+ * @short Performs constant propagation, also called constant folding, on this expression.
+ *
+ * This means that it attempts to evaluate this expression at compile and returns the result value
+ * appropriately as an Expression. For example, for the XPath expression
+ * <tt>1 + 3</tt> would an Integer of value 4 would be returned.
+ *
+ * It is not checked whether constant propagation is possible, the
+ * caller is responsible for this.
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Constant_propagation">Constant folding,
+ * From Wikipedia, the free encyclopedia</a>
+ */
+ Expression::Ptr constantPropagate(const StaticContext::Ptr &context) const;
+
+ Q_DISABLE_COPY(Expression)
+ };
+
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Expression::Properties)
+
+ inline bool Expression::is(const Expression::ID i) const
+ {
+ return id() == i;
+ }
+
+ inline bool Expression::isEvaluated() const
+ {
+ return has(IsEvaluated);
+ }
+
+ inline bool Expression::has(const Expression::Property prop) const
+ {
+ return properties().testFlag(prop);
+ }
+
+ inline bool Expression::hasDependency(const Expression::Property prop) const
+ {
+ return dependencies().testFlag(prop);
+ }
+
+ inline void Expression::rewrite(Expression::Ptr &old,
+ const Expression::Ptr &New,
+ const StaticContext::Ptr &context)
+ {
+ Q_ASSERT(old);
+ Q_ASSERT(New);
+
+ if(old != New)
+ {
+ pDebug() << "AST REWRITE:" << old.data() << "to" << New.data()
+ << '(' << old->actualReflection() << "to" << New->actualReflection() << ", "
+ << old->description() << "to" << New->description() << ')';
+
+ /* The order of these two lines is significant.. */
+ context->addLocation(New.data(), context->locationFor(old->actualReflection()));
+ old = New;
+ }
+ }
+
+ inline const Expression::Ptr &Expression::rewrite(const Expression::Ptr &to,
+ const StaticContext::Ptr &context) const
+ {
+ context->addLocation(to.data(), context->locationFor(this));
+ return to;
+ }
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::Expression::Ptr, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressiondispatch_p.h b/src/xmlpatterns/expr/qexpressiondispatch_p.h
new file mode 100644
index 0000000..23b2408
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressiondispatch_p.h
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ExpressionDispatch_H
+#define Patternist_ExpressionDispatch_H
+
+#include <QSharedData>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class AndExpression;
+ class ApplyTemplate;
+ class ArgumentConverter;
+ class ArgumentReference;
+ class ArithmeticExpression;
+ class Atomizer;
+ class AttributeConstructor;
+ class AttributeNameValidator;
+ class AxisStep;
+ class CallTemplate;
+ class CardinalityVerifier;
+ class CardinalityVerifier;
+ class CastableAs;
+ class CastableAs;
+ class CastAs;
+ class CastAs;
+ class CollationChecker;
+ class CollationChecker;
+ class CombineNodes;
+ class CombineNodes;
+ class CommentConstructor;
+ class CommentConstructor;
+ class ComputedNamespaceConstructor;
+ class ContextItem;
+ class CopyOf;
+ class CurrentItemStore;
+ class DocumentConstructor;
+ class DynamicContextStore;
+ class EBVExtractor;
+ class ElementConstructor;
+ class EmptySequence;
+ class ExpressionSequence;
+ class ExpressionVariableReference;
+ class ExternalVariableReference;
+ class FirstItemPredicate;
+ class ForClause;
+ class FunctionCall;
+ class GeneralComparison;
+ class GenericPredicate;
+ class IfThenClause;
+ class InstanceOf;
+ class ItemVerifier;
+ class LetClause;
+ class Literal;
+ class LiteralSequence;
+ class NamespaceConstructor;
+ class NCNameConstructor;
+ class NodeComparison;
+ class NodeSortExpression;
+ class OrderBy;
+ class OrExpression;
+ class ParentNodeAxis;
+ class Path;
+ class PositionalVariableReference;
+ class ProcessingInstructionConstructor;
+ class QNameConstructor;
+ class QuantifiedExpression;
+ class RangeExpression;
+ class RangeVariableReference;
+ class ReturnOrderBy;
+ class SimpleContentConstructor;
+ class StaticBaseURIStore;
+ class StaticCompatibilityStore;
+ class TemplateParameterReference;
+ class TextNodeConstructor;
+ class TreatAs;
+ class TruthPredicate;
+ class UnresolvedVariableReference;
+ class UntypedAtomicConverter;
+ class UserFunctionCallsite;
+ class ValidationError;
+ class ValueComparison;
+ template<bool IsForGlobal> class EvaluationCache;
+
+ /**
+ * @todo Documentation's missing
+ *
+ * @defgroup Patternist_expr_dispatch Expression Dispatching
+ */
+
+ /**
+ * @ingroup Patternist_expr_dispatch
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ExpressionVisitorResult : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionVisitorResult> Ptr;
+ ExpressionVisitorResult() {}
+ virtual ~ExpressionVisitorResult() {}
+ };
+
+ /**
+ * @ingroup Patternist_expr_dispatch
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ExpressionVisitor : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionVisitor> Ptr;
+ virtual ~ExpressionVisitor() {}
+
+ virtual ExpressionVisitorResult::Ptr visit(const AndExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ApplyTemplate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ArgumentConverter *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ArgumentReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ArithmeticExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const Atomizer *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const AttributeConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const AttributeNameValidator *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const AxisStep *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CallTemplate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CardinalityVerifier *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CastableAs *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CastAs *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CollationChecker *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CombineNodes *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CommentConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ComputedNamespaceConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ContextItem *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CopyOf *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CurrentItemStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const DocumentConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const DynamicContextStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EBVExtractor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ElementConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EmptySequence *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EvaluationCache<false> *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EvaluationCache<true> *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ExpressionSequence *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ExpressionVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ExternalVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const FirstItemPredicate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ForClause *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const FunctionCall *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const GeneralComparison *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const GenericPredicate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const IfThenClause *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const InstanceOf *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ItemVerifier *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const LetClause *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const Literal *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const LiteralSequence *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NamespaceConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NCNameConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NodeComparison *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NodeSortExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const OrderBy *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const OrExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ParentNodeAxis *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const Path *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const PositionalVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ProcessingInstructionConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const QNameConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const QuantifiedExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const RangeExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const RangeVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ReturnOrderBy *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const SimpleContentConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const StaticBaseURIStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const StaticCompatibilityStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TemplateParameterReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TextNodeConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TreatAs *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TruthPredicate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const UnresolvedVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const UntypedAtomicConverter *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const UserFunctionCallsite *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ValidationError *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ValueComparison *) const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressionfactory.cpp b/src/xmlpatterns/expr/qexpressionfactory.cpp
new file mode 100644
index 0000000..861b980
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionfactory.cpp
@@ -0,0 +1,473 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QBuffer>
+#include <QByteArray>
+
+#include "qcalltemplate_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qdebug_p.h"
+#include "qexpression_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qoperandsiterator_p.h"
+#include "qoptimizationpasses_p.h"
+#include "qparsercontext_p.h"
+#include "qpath_p.h"
+#include "qquerytransformparser_p.h"
+#include "qstaticfocuscontext_p.h"
+#include "qtokenrevealer_p.h"
+#include "qxquerytokenizer_p.h"
+#include "qxslttokenizer_p.h"
+
+#include "qexpressionfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist {
+
+/**
+ * @short The entry point to the parser.
+ *
+ * @param info supplies the information the parser & scanner
+ * needs to create expressions. The created expression, if everything
+ * succeeds, can be retrieved via the object @p info points to.
+ * @returns non-negative if the parser fails.
+ * @see ExpressionFactory::createExpression()
+ */
+extern int XPathparse(QPatternist::ParserContext *const info);
+
+Expression::Ptr ExpressionFactory::createExpression(const QString &expr,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName)
+{
+ if(lang == QXmlQuery::XSLT20)
+ {
+ QByteArray query(expr.toUtf8());
+ QBuffer buffer(&query);
+ buffer.open(QIODevice::ReadOnly);
+
+ return createExpression(&buffer,
+ context,
+ lang,
+ requiredType,
+ queryURI,
+ initialTemplateName);
+ }
+ else
+ {
+ return createExpression(Tokenizer::Ptr(new XQueryTokenizer(expr, queryURI)),
+ context,
+ lang,
+ requiredType,
+ queryURI,
+ initialTemplateName);
+ }
+}
+
+Expression::Ptr ExpressionFactory::createExpression(QIODevice *const device,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName)
+{
+ Q_ASSERT(device);
+ Q_ASSERT(device->isReadable());
+
+ Tokenizer::Ptr tokenizer;
+
+ if(lang == QXmlQuery::XSLT20)
+ tokenizer = Tokenizer::Ptr(new XSLTTokenizer(device, queryURI, context, context->namePool()));
+ else
+ tokenizer = Tokenizer::Ptr(new XQueryTokenizer(QString::fromUtf8(device->readAll()), queryURI));
+
+ return createExpression(tokenizer, context, lang, requiredType, queryURI, initialTemplateName);
+}
+
+Expression::Ptr ExpressionFactory::createExpression(const Tokenizer::Ptr &tokenizer,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName)
+{
+ Q_ASSERT(context);
+ Q_ASSERT(requiredType);
+ Q_ASSERT(queryURI.isValid());
+
+ Tokenizer::Ptr effectiveTokenizer(tokenizer);
+#ifdef Patternist_DEBUG
+ effectiveTokenizer = Tokenizer::Ptr(new TokenRevealer(queryURI, tokenizer));
+#endif
+
+ OptimizationPasses::Coordinator::init();
+
+ const ParserContext::Ptr info(new ParserContext(context, lang, effectiveTokenizer.data()));
+ info->initialTemplateName = initialTemplateName;
+
+ effectiveTokenizer->setParserContext(info);
+
+ const int bisonRetval = XPathparse(info.data());
+
+ Q_ASSERT_X(bisonRetval == 0, Q_FUNC_INFO,
+ "We shouldn't be able to get an error, because we throw exceptions.");
+ Q_UNUSED(bisonRetval); /* Needed when not compiled in debug mode, since bisonRetval won't
+ * be used in the Q_ASSERT_X above. */
+
+ Expression::Ptr result(info->queryBody);
+
+ if(!result)
+ {
+ context->error(QtXmlPatterns::tr("A library module cannot be evaluated "
+ "directly. It must be imported from a "
+ "main module."),
+ ReportContext::XPST0003,
+ QSourceLocation(queryURI, 1, 1));
+ }
+
+ /* Optimization: I think many things are done in the wrong order below. We
+ * probably want everything typechecked before compressing, since we can
+ * have references all over the place(variable references, template
+ * invocations, function callsites). This could even be a source to bugs.
+ */
+
+ /* Here, we type check user declared functions and global variables. This
+ * means that variables and functions that are not used are type
+ * checked(which they otherwise wouldn't have been), and those which are
+ * used, are type-checked twice, unfortunately. */
+
+ const bool hasExternalFocus = context->contextItemType();
+
+ if(lang == QXmlQuery::XSLT20)
+ {
+ /* Bind xsl:call-template instructions to their template bodies.
+ *
+ * We do this before type checking and compressing them, because a
+ * CallTemplate obviously needs its template before being compressed.
+ *
+ * Also, we do this before type checking and compressing user
+ * functions, since they can contain template call sites.
+ */
+ for(int i = 0; i < info->templateCalls.count(); ++i)
+ {
+ CallTemplate *const site = info->templateCalls.at(i)->as<CallTemplate>();
+ const QXmlName targetName(site->name());
+ const Template::Ptr t(info->namedTemplates.value(targetName));
+
+ if(t)
+ site->setTemplate(t);
+ else
+ {
+ context->error(QtXmlPatterns::tr("No template by name %1 exists.").arg(formatKeyword(context->namePool(), targetName)),
+ ReportContext::XTSE0650,
+ site);
+ }
+ }
+ }
+
+ /* Type check and compress user functions. */
+ {
+ const UserFunction::List::const_iterator end(info->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(info->userFunctions.constBegin());
+
+ /* If the query has a focus(which is common, in the case of a
+ * stylesheet), we must ensure that the focus isn't visible in the
+ * function body. */
+ StaticContext::Ptr effectiveContext;
+
+ if(hasExternalFocus)
+ {
+ effectiveContext = StaticContext::Ptr(new StaticFocusContext(ItemType::Ptr(),
+ context));
+ }
+ else
+ effectiveContext = context;
+
+ for(; it != end; ++it)
+ {
+ pDebug() << "----- User Function Typecheck -----";
+ registerLastPath((*it)->body());
+
+ /* We will most likely call body()->typeCheck() again, once for
+ * each callsite. That is, it will be called from
+ * UserFunctionCallsite::typeCheck(), which will be called
+ * indirectly when we check the query body. */
+ const Expression::Ptr typeCheck((*it)->body()->typeCheck(effectiveContext,
+ (*it)->signature()->returnType()));
+ /* We don't have to call (*it)->setBody(typeCheck) here since it's
+ * only used directly below. */
+ processTreePass(typeCheck, UserFunctionTypeCheck);
+ pDebug() << "------------------------------";
+
+ pDebug() << "----- User Function Compress -----";
+ const Expression::Ptr comp(typeCheck->compress(effectiveContext));
+ (*it)->setBody(comp);
+ processTreePass(comp, UserFunctionCompression);
+ pDebug() << "------------------------------";
+ }
+ }
+
+ /* Type check and compress global variables. */
+ {
+ const VariableDeclaration::Stack::const_iterator vend(info->variables.constEnd());
+ VariableDeclaration::Stack::const_iterator vit(info->variables.constBegin());
+ for(; vit != vend; ++vit)
+ {
+ Q_ASSERT(*vit);
+ /* This is a bit murky, the global variable will have it
+ * Expression::typeCheck() function called from all its references,
+ * but we also want to check it here globally, so we do
+ * typechecking using a proper focus. */
+ if((*vit)->type == VariableDeclaration::ExternalVariable)
+ continue;
+
+ pDebug() << "----- Global Variable Typecheck -----";
+ Q_ASSERT((*vit)->expression());
+ /* We supply ZeroOrMoreItems, meaning the variable can evaluate to anything. */
+ // FIXME which is a source to bugs
+ // TODO What about compressing variables?
+ const Expression::Ptr
+ nev((*vit)->expression()->typeCheck(context, CommonSequenceTypes::ZeroOrMoreItems));
+ processTreePass(nev, GlobalVariableTypeCheck);
+ pDebug() << "------------------------------";
+ }
+ }
+
+ /* Do all tests specific to XSL-T. */
+ if(lang == QXmlQuery::XSLT20)
+ {
+ /* Type check and compress named templates. */
+ {
+ pDebug() << "Have " << info->namedTemplates.count() << "named templates";
+
+ QMutableHashIterator<QXmlName, Template::Ptr> it(info->namedTemplates);
+
+ while(it.hasNext())
+ {
+ it.next();
+ processNamedTemplate(it.key(), it.value()->body, TemplateInitial);
+
+ it.value()->body = it.value()->body->typeCheck(context, CommonSequenceTypes::ZeroOrMoreItems);
+ processNamedTemplate(it.key(), it.value()->body, TemplateTypeCheck);
+
+ it.value()->body = it.value()->body->compress(context);
+ processNamedTemplate(it.key(), it.value()->body, TemplateCompress);
+
+ it.value()->compileParameters(context);
+ }
+ }
+
+ /* Type check and compress template rules. */
+ {
+ QHashIterator<QXmlName, TemplateMode::Ptr> it(info->templateRules);
+
+ /* Since a pattern can exist of AxisStep, its typeCheck() stage
+ * requires a focus. In the case that we're invoked with a name but
+ * no focus, this will yield a compile error, unless we declare a
+ * focus manually. This only needs to be done for the pattern
+ * expression, since the static type of the pattern is used as the
+ * static type for the focus of the template body. */
+ StaticContext::Ptr patternContext;
+ if(hasExternalFocus)
+ patternContext = context;
+ else
+ patternContext = StaticContext::Ptr(new StaticFocusContext(BuiltinTypes::node, context));
+
+ /* For each template pattern. */
+ while(it.hasNext())
+ {
+ it.next();
+ const TemplateMode::Ptr &mode = it.value();
+ const int len = mode->templatePatterns.count();
+ TemplatePattern::ID currentTemplateID = -1;
+ bool hasDoneItOnce = false;
+
+ /* For each template pattern. */
+ for(int i = 0; i < len; ++i)
+ {
+ /* We can't use references for these two members, since we
+ * assign to them. */
+ const TemplatePattern::Ptr &pattern = mode->templatePatterns.at(i);
+ Expression::Ptr matchPattern(pattern->matchPattern());
+
+ processTemplateRule(pattern->templateTarget()->body,
+ pattern, mode->name(), TemplateInitial);
+
+ matchPattern = matchPattern->typeCheck(patternContext, CommonSequenceTypes::ZeroOrMoreItems);
+ matchPattern = matchPattern->compress(patternContext);
+ pattern->setMatchPattern(matchPattern);
+
+ if(currentTemplateID == -1 && hasDoneItOnce)
+ {
+ currentTemplateID = pattern->id();
+ continue;
+ }
+ else if(currentTemplateID == pattern->id() && hasDoneItOnce)
+ {
+ hasDoneItOnce = false;
+ continue;
+ }
+
+ hasDoneItOnce = true;
+ currentTemplateID = pattern->id();
+ Expression::Ptr body(pattern->templateTarget()->body);
+
+ /* Patterns for a new template has started, we must
+ * deal with the body & parameters. */
+ {
+ /* TODO type is wrong, it has to be the union of all
+ * patterns. */
+ const StaticContext::Ptr focusContext(new StaticFocusContext(matchPattern->staticType()->itemType(),
+ context));
+ body = body->typeCheck(focusContext, CommonSequenceTypes::ZeroOrMoreItems);
+
+ pattern->templateTarget()->compileParameters(focusContext);
+ }
+
+ processTemplateRule(body, pattern, mode->name(), TemplateTypeCheck);
+
+ body = body->compress(context);
+
+ pattern->templateTarget()->body = body;
+ processTemplateRule(body, pattern, mode->name(), TemplateCompress);
+ }
+
+ mode->finalize();
+ }
+ }
+
+ /* Add templates in mode #all to all other modes.
+ *
+ * We do this after the templates has been typechecked and compressed,
+ * since otherwise it will be done N times for the built-in templates,
+ * where N is the count of different templates, instead of once. */
+ {
+ const QXmlName nameModeAll(QXmlName(StandardNamespaces::InternalXSLT,
+ StandardLocalNames::all));
+ const TemplateMode::Ptr &modeAll = info->templateRules[nameModeAll];
+
+ Q_ASSERT_X(modeAll, Q_FUNC_INFO,
+ "We should at least have the builtin templates.");
+ QHashIterator<QXmlName, TemplateMode::Ptr> it(info->templateRules);
+
+ while(it.hasNext())
+ {
+ it.next();
+
+ /* Don't add mode #all to mode #all. */
+ if(it.key() == nameModeAll)
+ continue;
+
+ it.value()->addMode(modeAll);
+ }
+ }
+ }
+
+ /* Type check and compress the query body. */
+ {
+ pDebug() << "----- Initial AST build. -----";
+ processTreePass(result, QueryBodyInitial);
+ pDebug() << "------------------------------";
+
+ pDebug() << "----- Type Check -----";
+ registerLastPath(result);
+ result->rewrite(result, result->typeCheck(context, requiredType), context);
+ processTreePass(result, QueryBodyTypeCheck);
+ pDebug() << "------------------------------";
+
+ pDebug() << "----- Compress -----";
+ result->rewrite(result, result->compress(context), context);
+ processTreePass(result, QueryBodyCompression);
+ pDebug() << "------------------------------";
+ }
+
+ return result;
+}
+
+void ExpressionFactory::registerLastPath(const Expression::Ptr &operand)
+{
+ OperandsIterator it(operand, OperandsIterator::IncludeParent);
+ Expression::Ptr next(it.next());
+
+ while(next)
+ {
+ if(next->is(Expression::IDPath))
+ {
+ next->as<Path>()->setLast();
+ next = it.skipOperands();
+ }
+ else
+ next = it.next();
+ }
+}
+
+void ExpressionFactory::processTreePass(const Expression::Ptr &,
+ const CompilationStage)
+{
+}
+
+void ExpressionFactory::processTemplateRule(const Expression::Ptr &body,
+ const TemplatePattern::Ptr &pattern,
+ const QXmlName &mode,
+ const TemplateCompilationStage stage)
+{
+ Q_UNUSED(body);
+ Q_UNUSED(pattern);
+ Q_UNUSED(mode);
+ Q_UNUSED(stage);
+}
+
+void ExpressionFactory::processNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &tree,
+ const TemplateCompilationStage stage)
+{
+ Q_UNUSED(name);
+ Q_UNUSED(tree);
+ Q_UNUSED(stage);
+}
+
+} // namespace QPatternist
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/expr/qexpressionfactory_p.h b/src/xmlpatterns/expr/qexpressionfactory_p.h
new file mode 100644
index 0000000..07235bb
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionfactory_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ExpressionFactory_H
+#define Patternist_ExpressionFactory_H
+
+#include <QXmlQuery>
+
+#include "qexpression_p.h"
+#include "qtokenizer_p.h"
+
+#include <QSharedData>
+#include <QUrl>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+
+namespace QPatternist
+{
+ /**
+ * @short The central entry point for compiling expressions.
+ *
+ * @ingroup Patternist_expressions
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT ExpressionFactory : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionFactory> Ptr;
+
+ /**
+ * @short This constructor cannot be synthesized since we
+ * use the Q_DISABLE_COPY macro.
+ */
+ inline ExpressionFactory()
+ {
+ }
+
+ virtual ~ExpressionFactory()
+ {
+ }
+
+ enum CompilationStage
+ {
+ QueryBodyInitial = 1,
+ QueryBodyTypeCheck = 1 << 1,
+ QueryBodyCompression = 1 << 2,
+ UserFunctionTypeCheck = 1 << 3,
+ UserFunctionCompression = 1 << 4,
+ GlobalVariableTypeCheck = 1 << 5
+ };
+
+ /**
+ * Creates a compiled representation of the XPath expression @p expr, with Static
+ * Context information supplied via @p context. This is for example whether the expression
+ * is an XPath 1.0 or XPath 2.0 expression, or what functions that are available.
+ *
+ * @p requiredType specifies what type results of the evaluating the expression
+ * must match. Passing CommonValues::ZeroOrMoreItems allows anything as result, while
+ * passing CommonSequenceTypes::EBV means anything but an Effective %Boolean Value extractable
+ * result is a type error, for example.
+ *
+ * @note An empty @p expr is an invalid XPath expression. It will be reported as such,
+ * but it is neverthless the caller's resonsibility to ensure that it's not that(since
+ * it is likely invalid already in the medium it was stored).
+ */
+ virtual Expression::Ptr createExpression(const QString &expr,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName);
+
+ virtual Expression::Ptr createExpression(QIODevice *const device,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName);
+
+ /**
+ * Finds the last paths of a set of paths(if any) and tells the Path
+ * so, such that it can generate the code for checking XPTY0018.
+ *
+ * Must be called before typeCheck() is called on the operand, since
+ * the typeCheck() uses the information for type checking.
+ */
+ static void registerLastPath(const Expression::Ptr &operand);
+
+ protected:
+ enum TemplateCompilationStage
+ {
+ TemplateInitial = 1,
+ TemplateTypeCheck = 1 << 1,
+ TemplateCompress = 1 << 2
+ };
+
+ /**
+ * This function is called by createExpression() each time
+ * after a pass on the AST has been completed. Under a typical
+ * compilation this function is thus called three times: after the initial
+ * build, after the Expression::typeCheck() stage, and after
+ * Expression::compress(). @p tree is the AST after each pass.
+ *
+ * This mechanism is currently used for debugging, since it provides a
+ * way of introspecting what the compilation process do to the tree. The
+ * current implementation do nothing.
+ */
+ virtual void processTreePass(const Expression::Ptr &tree,
+ const CompilationStage stage);
+
+ virtual void processTemplateRule(const Expression::Ptr &body,
+ const TemplatePattern::Ptr &pattern,
+ const QXmlName &mode,
+ const TemplateCompilationStage stage);
+
+ virtual void processNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &tree,
+ const TemplateCompilationStage stage);
+
+ Expression::Ptr createExpression(const Tokenizer::Ptr &tokenizer,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName);
+ private:
+ Q_DISABLE_COPY(ExpressionFactory)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressionsequence.cpp b/src/xmlpatterns/expr/qexpressionsequence.cpp
new file mode 100644
index 0000000..a4d1ba6
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionsequence.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcardinalityverifier_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qexpressionsequence_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExpressionSequence::ExpressionSequence(const Expression::List &ops) : UnlimitedContainer(ops)
+{
+ Q_ASSERT_X(1 < ops.count(), Q_FUNC_INFO,
+ "It makes no sense to have an ExpressionSequence containing less than two expressions.");
+}
+
+Item::Iterator::Ptr ExpressionSequence::mapToSequence(const Expression::Ptr &expr,
+ const DynamicContext::Ptr &context) const
+{
+ return expr->evaluateSequence(context);
+}
+
+Item::Iterator::Ptr ExpressionSequence::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ makeListIterator(m_operands),
+ context);
+}
+
+void ExpressionSequence::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ Expression::List::const_iterator it(m_operands.constBegin());
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List result;
+
+ for(; it != end; ++it)
+ (*it)->evaluateToSequenceReceiver(context);
+}
+
+Expression::Ptr ExpressionSequence::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(UnlimitedContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ Expression::List::const_iterator it(m_operands.constBegin());
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List result;
+
+ for(; it != end; ++it)
+ {
+ const ID Id = (*it)->id();
+
+ /* Remove empty sequences. This is rather important because we have some steps in the parser that
+ * intentionally, unconditionally and for temporary reasons create expressions like (expr, ()). Of course,
+ * empty sequences also occur as part of optimizations.
+ *
+ * User function call sites that are of type empty-sequence() must be avoided since
+ * they may contain calls to fn:error(), which we would rewrite away otherwise. */
+ if(Id != IDUserFunctionCallsite && (*it)->staticType()->cardinality().isEmpty())
+ {
+ /* Rewrite "(1, (), 2)" into "(1, 2)" by not
+ * adding (*it) to result. */
+ continue;
+ }
+ else if(Id == IDExpressionSequence)
+ {
+ /* Rewrite "(1, (2, 3), 4)" into "(1, 2, 3, 4)" */
+ Expression::List::const_iterator seqIt((*it)->operands().constBegin());
+ const Expression::List::const_iterator seqEnd((*it)->operands().constEnd());
+
+ for(; seqIt != seqEnd; ++seqIt)
+ result.append(*seqIt);
+ }
+ else
+ result.append(*it);
+ }
+
+ if(result.isEmpty())
+ return EmptySequence::create(this, context);
+ else if(result.count() == 1)
+ return result.first();
+ else
+ {
+ m_operands = result;
+ return me;
+ }
+}
+
+Expression::Ptr ExpressionSequence::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(reqType);
+ Expression::List::iterator it(m_operands.begin());
+ const Expression::List::iterator end(m_operands.end());
+
+ /* We treat the cardinality differently here by allowing the empty sequence
+ * for each individual Expression, since the Cardinality can be conformed to by
+ * the ExpressionSequence as a whole(which we check for at the end). */
+ const SequenceType::Ptr testOnlyIT(makeGenericSequenceType(reqType->itemType(),
+ Cardinality::empty() |
+ reqType->cardinality()));
+
+ for(; it != end; ++it)
+ *it = (*it)->typeCheck(context, testOnlyIT);
+
+ /* The above loop is only guaranteed to find item type errors, but the cardinality
+ * can still be wrong since the operands were treated individually. */
+ return CardinalityVerifier::verifyCardinality(Expression::Ptr(this), reqType->cardinality(), context);
+}
+
+Expression::Properties ExpressionSequence::properties() const
+{
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List::const_iterator it;
+ bool allEvaled = true;
+ Expression::Properties props(DisableElimination); /* Why do we have this flag? */
+
+ for(it = m_operands.constBegin(); it != end; ++it)
+ {
+ const Expression::Properties newp((*it)->properties());
+ props |= newp;
+
+ if((newp & IsEvaluated) != IsEvaluated)
+ {
+ allEvaled = false;
+ break;
+ }
+ }
+
+ if(!allEvaled)
+ props &= ~IsEvaluated; /* Remove IsEvaluated. */
+
+ /* One of our children might need the focus, but we don't, so
+ * cut it out. */
+ return props & ~RequiresFocus;
+}
+
+SequenceType::Ptr ExpressionSequence::staticType() const
+{
+ return operandsUnionType<ProductOfCardinality>();
+}
+
+SequenceType::List ExpressionSequence::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ /* ExpressionSequence is a bit strange type wise since it has an
+ * infinite amount of operands. */
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr ExpressionSequence::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ExpressionSequence::id() const
+{
+ return IDExpressionSequence;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexpressionsequence_p.h b/src/xmlpatterns/expr/qexpressionsequence_p.h
new file mode 100644
index 0000000..5074489
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionsequence_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ExpressionSequence_H
+#define Patternist_ExpressionSequence_H
+
+#include "qunlimitedcontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the comma(",") operator, the sequence constructor.
+ *
+ * For example, the expression <tt>alpha, beta</tt> evaluates to a sequence
+ * containing the items the nodetest @c alpha evaluates to, concatenated
+ * with the items the nodetest @c beta evaluates to.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#construct_seq">XML Path Language
+ * (XPath) 2.0, 3.3.1 Constructing Sequences</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionSequence : public UnlimitedContainer
+ {
+ public:
+ /**
+ * Creates an ExpressionSequence with the operands @p operands. @p operands
+ * must contain two or more Expression instances.
+ */
+ ExpressionSequence(const Expression::List &operands);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+
+ /**
+ * Forwards the call to its children.
+ */
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Removes any empty sequences, typically "()", from its list of children. If
+ * after that rewrite has no children, it rewrites itself to the CommonValues::empty;
+ * if it has only one, it rewrites to the child.
+ *
+ * This optimization is not very usable by itself, but potentially becomes effective after other
+ * optimizations have rewritten themselves into empty sequences. Thus,
+ * saving memory consumption and runtime overhead.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ inline Item::Iterator::Ptr mapToSequence(const Expression::Ptr &,
+ const DynamicContext::Ptr &) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ /**
+ * @returns Expression::DisableElimination, plus the union
+ * of all this ExpressionSequence's children's properties. If any child
+ * does not have IsEvaluated, it is removed from the result.
+ */
+ virtual Expression::Properties properties() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+ private:
+ typedef QExplicitlySharedDataPointer<const ExpressionSequence> ConstPtr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressionvariablereference.cpp b/src/xmlpatterns/expr/qexpressionvariablereference.cpp
new file mode 100644
index 0000000..3b9ecb1
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionvariablereference.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qexpressionvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExpressionVariableReference::ExpressionVariableReference(const VariableSlotID slotP,
+ const VariableDeclaration::Ptr &varDecl) : VariableReference(slotP)
+ , m_varDecl(varDecl)
+{
+}
+
+bool ExpressionVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateEBV(context);
+}
+
+Item ExpressionVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr ExpressionVariableReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSequence(context);
+}
+Expression::Ptr ExpressionVariableReference::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(m_varDecl->canSourceRewrite)
+ return m_varDecl->expression()->typeCheck(context, reqType);
+ else
+ return VariableReference::typeCheck(context, reqType);
+}
+
+Expression::ID ExpressionVariableReference::id() const
+{
+ return IDExpressionVariableReference;
+}
+
+ExpressionVisitorResult::Ptr ExpressionVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr ExpressionVariableReference::staticType() const
+{
+ return m_varDecl->expression()->staticType();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexpressionvariablereference_p.h b/src/xmlpatterns/expr/qexpressionvariablereference_p.h
new file mode 100644
index 0000000..40c835e
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionvariablereference_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ExpressionVariableReference_H
+#define Patternist_ExpressionVariableReference_H
+
+#include "qvariabledeclaration_p.h"
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to a variable declared with <tt>declare variable</tt> or @c let.
+ *
+ * It's also used by variable bindings in @c case branches of the @c typeswitch
+ * expression.
+ *
+ * This AST node is only used up until the typeCheck() stage. Therefore it
+ * has no functions for evaluation, such as evaluateSequence().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionVariableReference : public VariableReference
+ {
+ public:
+ ExpressionVariableReference(const VariableSlotID slot,
+ const VariableDeclaration::Ptr &varDecl);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual ID id() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline const Expression::Ptr &sourceExpression() const;
+ inline const VariableDeclaration::Ptr &variableDeclaration() const;
+ private:
+ const VariableDeclaration::Ptr m_varDecl;
+ };
+
+ inline const Expression::Ptr &ExpressionVariableReference::sourceExpression() const
+ {
+ return m_varDecl->expression();
+ }
+
+ inline const VariableDeclaration::Ptr &ExpressionVariableReference::variableDeclaration() const
+ {
+ return m_varDecl;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexternalvariableloader.cpp b/src/xmlpatterns/expr/qexternalvariableloader.cpp
new file mode 100644
index 0000000..2099cb6
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariableloader.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qdynamiccontext_p.h"
+
+#include "qexternalvariableloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExternalVariableLoader::~ExternalVariableLoader()
+{
+}
+
+
+SequenceType::Ptr ExternalVariableLoader::announceExternalVariable(const QXmlName name,
+ const SequenceType::Ptr &declaredType)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(declaredType);
+ Q_UNUSED(name); /* Needed when compiling in release mode. */
+ Q_UNUSED(declaredType); /* Needed when compiling in release mode. */
+
+ return SequenceType::Ptr();
+}
+
+Item::Iterator::Ptr ExternalVariableLoader::evaluateSequence(const QXmlName name,
+ const DynamicContext::Ptr &context)
+{
+ Q_ASSERT(!name.isNull());
+ const Item item(evaluateSingleton(name, context));
+
+ if(item)
+ return makeSingletonIterator(item);
+ else
+ return CommonValues::emptyIterator;
+}
+
+Item ExternalVariableLoader::evaluateSingleton(const QXmlName name,
+ const DynamicContext::Ptr &context)
+{
+ Q_ASSERT(!name.isNull());
+ return Boolean::fromValue(evaluateEBV(name, context));
+}
+
+bool ExternalVariableLoader::evaluateEBV(const QXmlName name,
+ const DynamicContext::Ptr &context)
+{
+ Q_ASSERT(!name.isNull());
+ return Boolean::evaluateEBV(evaluateSequence(name, context), context);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexternalvariableloader_p.h b/src/xmlpatterns/expr/qexternalvariableloader_p.h
new file mode 100644
index 0000000..5dc3af5
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariableloader_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ExternalVariableLoader_H
+#define Patternist_ExternalVariableLoader_H
+
+#include "qitem_p.h"
+#include "qsequencetype_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class DynamicContext;
+
+ /**
+ * @short Responsible for loading and declaring available external variables.
+ *
+ * An external variable in XQuery is a global variable that has been declared to receive
+ * its value from the XQuery implementation, as opposed to an initializing expression. Here
+ * is an example of a query with an external variable declaration, followed by a ordinary
+ * global variable:
+ *
+ * <tt> declare variable $theName external;
+ * declare variable $theName := "the value";
+ * "And here's the query body(a string literal)"</tt>
+ *
+ * An external variable declaration can also specify a sequence type:
+ *
+ * <tt>declare variable $theName as xs:integer external;</tt>
+ *
+ * This class allows the user to supply the values to external variables. When
+ * an external variable declaration occur in the query,
+ * announceExternalVariable() is called.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT ExternalVariableLoader : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExternalVariableLoader> Ptr;
+ inline ExternalVariableLoader() {}
+
+ virtual ~ExternalVariableLoader();
+
+ /**
+ * Called when Patternist encounters an external variable in the query. It is guaranteed
+ * to be called once for each external variable appearing in a query module.
+ *
+ * @param name the name of the variable. Quaranteed to never be @c null.
+ * @param declaredType the type that the user declared the variable to be of. Whether
+ * this type matches the actual value of the variable or not is irrelevant. Patternist
+ * will do the necessary error handling based on the sequence type that is returned from
+ * this function. If the user didn't declare a type, the type is <tt>item()*</tt>(zero or
+ * more items). Quaranteed to never be @c null.
+ * @returns the sequence type of the value this ExternalVariableLoader actually supplies. However,
+ * if the ExternalVariableLoader knows it cannot supply a variable by this name, @c null should be
+ * returned.
+ */
+ virtual SequenceType::Ptr announceExternalVariable(const QXmlName name,
+ const SequenceType::Ptr &declaredType);
+
+ /**
+ * This function is called at runtime when the external variable by name @p name needs
+ * to be evaluated. It is not defined how many times this function will be called. It
+ * depends on aspects such as how the query was optimized.
+ *
+ * @param name the name of the variable. Quaranteed to never be @c null.
+ * @param context the DynamicContext.
+ * @returns the value of the variable. Remember that this value must match the
+ * sequence type returned from announceExternalVariable() for the same name.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const QXmlName name,
+ const QExplicitlySharedDataPointer<DynamicContext> &context);
+
+ virtual Item evaluateSingleton(const QXmlName name,
+ const QExplicitlySharedDataPointer<DynamicContext> &context);
+ virtual bool evaluateEBV(const QXmlName name,
+ const QExplicitlySharedDataPointer<DynamicContext> &context);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexternalvariablereference.cpp b/src/xmlpatterns/expr/qexternalvariablereference.cpp
new file mode 100644
index 0000000..8016cc5
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariablereference.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qexternalvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExternalVariableReference::ExternalVariableReference(const QXmlName &name,
+ const SequenceType::Ptr &type) : m_name(name),
+ m_seqType(type)
+{
+ Q_ASSERT(!m_name.isNull());
+ Q_ASSERT(m_seqType);
+}
+
+Item::Iterator::Ptr ExternalVariableReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context->externalVariableLoader());
+ return context->externalVariableLoader()->evaluateSequence(m_name, context);
+}
+
+Item ExternalVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->externalVariableLoader()->evaluateSingleton(m_name, context);
+}
+
+bool ExternalVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->externalVariableLoader()->evaluateEBV(m_name, context);
+}
+
+SequenceType::Ptr ExternalVariableReference::staticType() const
+{
+ return m_seqType;
+}
+
+Expression::Properties ExternalVariableReference::properties() const
+{
+ return DisableElimination;
+}
+
+ExpressionVisitorResult::Ptr ExternalVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexternalvariablereference_p.h b/src/xmlpatterns/expr/qexternalvariablereference_p.h
new file mode 100644
index 0000000..96d0dd2
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariablereference_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ExternalVariableReference_H
+#define Patternist_ExternalVariableReference_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to an external variable.
+ *
+ * ExternalVariableReference does not sub-class VariableReference, because it
+ * works differently from how sub-classes of VariableReference do. This class
+ * uses DynamicContext::externalVariableLoader() for retrieving its value, while
+ * a VariableReference sub-class uses slots in the DynamicContext.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExternalVariableReference : public EmptyContainer
+ {
+ public:
+ ExternalVariableReference(const QXmlName &name,
+ const SequenceType::Ptr &type);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns always DisableElimination
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const QXmlName m_name;
+ const SequenceType::Ptr m_seqType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qfirstitempredicate.cpp b/src/xmlpatterns/expr/qfirstitempredicate.cpp
new file mode 100644
index 0000000..651dff3
--- /dev/null
+++ b/src/xmlpatterns/expr/qfirstitempredicate.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qfirstitempredicate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+FirstItemPredicate::FirstItemPredicate(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item FirstItemPredicate::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ /* If our operand allows the empty sequence, this function can return Item(), otherwise
+ * it returns the first item. As simple as that. */
+ return m_operand->evaluateSequence(context)->next();
+}
+
+SequenceType::Ptr FirstItemPredicate::staticType() const
+{
+ const SequenceType::Ptr t(m_operand->staticType());
+ return makeGenericSequenceType(t->itemType(), t->cardinality().toWithoutMany());
+}
+
+Expression::Ptr FirstItemPredicate::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+ if(me != this)
+ return me;
+
+ if(m_operand->is(IDFirstItemPredicate))
+ m_operand = m_operand->operands().first();
+
+ return me;
+}
+
+SequenceType::List FirstItemPredicate::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr FirstItemPredicate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID FirstItemPredicate::id() const
+{
+ return IDFirstItemPredicate;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qfirstitempredicate_p.h b/src/xmlpatterns/expr/qfirstitempredicate_p.h
new file mode 100644
index 0000000..df44195
--- /dev/null
+++ b/src/xmlpatterns/expr/qfirstitempredicate_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_FirstItemPredicate_H
+#define Patternist_FirstItemPredicate_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A predicate that always selects the first item from its sequence.
+ *
+ * FirstItemPredicate corresponds exactly to the predicate
+ * in the expression <tt>input[1]</tt>.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class FirstItemPredicate : public SingleContainer
+ {
+ public:
+ /**
+ * Creates a FirstItemPredicate that filters @p source.
+ */
+ FirstItemPredicate(const Expression::Ptr &source);
+
+ /**
+ * @returns the first item, if any, from evaluating the source expression.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems instance.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns a SequenceType where the item type is the same as the source expression
+ * and where the cardinality is either Cardinality::zeroOrOne() or Cardinality::exactlyOne(),
+ * depending on the source expression.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Rewrites <tt>expression[1][1]</tt> into <tt>expression[1]</tt>.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns always IDFirstItemPredicate.
+ */
+ virtual ID id() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qforclause.cpp b/src/xmlpatterns/expr/qforclause.cpp
new file mode 100644
index 0000000..ad9262b
--- /dev/null
+++ b/src/xmlpatterns/expr/qforclause.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qoptimizationpasses_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qforclause_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ForClause::ForClause(const VariableSlotID varSlot,
+ const Expression::Ptr &bindingSequence,
+ const Expression::Ptr &returnExpression,
+ const VariableSlotID positionSlot) : PairContainer(bindingSequence, returnExpression),
+ m_varSlot(varSlot),
+ m_positionSlot(positionSlot),
+ m_allowsMany(true)
+{
+ Q_ASSERT(m_positionSlot > -2);
+}
+
+Item ForClause::mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ context->setRangeVariable(m_varSlot, item);
+ return m_operand2->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr ForClause::mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ context->setRangeVariable(m_varSlot, item);
+ return m_operand2->evaluateSequence(context);
+}
+
+void ForClause::riggPositionalVariable(const DynamicContext::Ptr &context,
+ const Item::Iterator::Ptr &source) const
+{
+ if(m_positionSlot > -1)
+ context->setPositionIterator(m_positionSlot, source);
+}
+
+Item::Iterator::Ptr ForClause::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ riggPositionalVariable(context, source);
+
+ if(m_allowsMany)
+ {
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ source,
+ context);
+ }
+ else
+ {
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ source,
+ context);
+ }
+}
+
+Item ForClause::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return evaluateSequence(context)->next();
+}
+
+void ForClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ Item::Iterator::Ptr it;
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ riggPositionalVariable(context, source);
+
+ Item next(source->next());
+
+ while(next)
+ {
+ context->setRangeVariable(m_varSlot, next);
+ m_operand2->evaluateToSequenceReceiver(context);
+ next = source->next();
+ }
+}
+
+Expression::Ptr ForClause::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+ const Cardinality card(m_operand1->staticType()->cardinality());
+
+ /* If our source is empty we will always evaluate to the empty sequence, so rewrite. */
+ if(card.isEmpty())
+ return EmptySequence::create(this, context);
+ else
+ return me;
+
+ /* This breaks because the variable references haven't rewritten themselves, so
+ * they dangle. When this is fixed, evaluateSingleton can be removed. */
+ /*
+ else if(card->allowsMany())
+ return me;
+ else
+ return m_operand2;
+ */
+}
+
+Expression::Ptr ForClause::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+ if(me != this)
+ return me;
+
+ /* This is done after calling PairContainer::typeCheck(). The advantage of this is that
+ * m_allowsMany is updated according to what the operand says after it has compressed. However,
+ * if it was initialized to false(as it once was..), ForClause::evaluateSequence()
+ * would potentially have been called by PairContainer::compress(), and it would have
+ * used an unsafe branch. */
+ m_allowsMany = m_operand2->staticType()->cardinality().allowsMany();
+
+ return me;
+}
+
+SequenceType::Ptr ForClause::staticType() const
+{
+ const SequenceType::Ptr returnType(m_operand2->staticType());
+
+ return makeGenericSequenceType(returnType->itemType(),
+ m_operand1->staticType()->cardinality()
+ * /* multiply operator */
+ returnType->cardinality());
+}
+
+SequenceType::List ForClause::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr ForClause::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+OptimizationPass::List ForClause::optimizationPasses() const
+{
+ return OptimizationPasses::forPasses;
+}
+
+Expression::ID ForClause::id() const
+{
+ return IDForClause;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qforclause_p.h b/src/xmlpatterns/expr/qforclause_p.h
new file mode 100644
index 0000000..5799e0d
--- /dev/null
+++ b/src/xmlpatterns/expr/qforclause_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ForClause_H
+#define Patternist_ForClause_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's @c for expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-for-expressions">XML Path Language
+ * (XPath) 2.0, 3.7 For Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ForClause : public PairContainer
+ {
+ public:
+ /**
+ * If @p positionSlot is -1, no positional variable will be used.
+ */
+ ForClause(const VariableSlotID varSlot,
+ const Expression::Ptr &bindingSequence,
+ const Expression::Ptr &returnExpression,
+ const VariableSlotID positionSlot);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ inline Item mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const;
+ virtual ID id() const;
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ /**
+ * Sets m_allowsMany properly.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ inline void riggPositionalVariable(const DynamicContext::Ptr &context,
+ const Item::Iterator::Ptr &source) const;
+ typedef QExplicitlySharedDataPointer<const ForClause> ConstPtr;
+ const VariableSlotID m_varSlot;
+ const VariableSlotID m_positionSlot;
+ /**
+ * Initialized to @c false. This default is always safe.
+ */
+ bool m_allowsMany;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qgeneralcomparison.cpp b/src/xmlpatterns/expr/qgeneralcomparison.cpp
new file mode 100644
index 0000000..a6d6399
--- /dev/null
+++ b/src/xmlpatterns/expr/qgeneralcomparison.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qebvextractor_p.h"
+#include "qitem_p.h"
+#include "qliteral_p.h"
+#include "qoptimizationpasses_p.h"
+#include "quntypedatomicconverter_p.h"
+#include "qvaluecomparison_p.h"
+
+#include "qgeneralcomparison_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GeneralComparison::GeneralComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2,
+ const bool isBackwardsCompat) : PairContainer(op1, op2)
+ , m_operator(op)
+ , m_isBackwardsCompat(isBackwardsCompat)
+{
+}
+
+bool GeneralComparison::generalCompare(const Item &op1,
+ const Item &op2,
+ const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(op1);
+ Q_ASSERT(op2);
+
+ if(comparator())
+ return compare(op1, op2, comparator(), m_operator);
+
+ Expression::Ptr a1(new Literal(op1));
+ Expression::Ptr a2(new Literal(op2));
+
+ const AtomicComparator::Ptr comp(fetchGeneralComparator(a1, a2, context));
+ /* The fetchGeneralComparator call may rewrite a1 and/or a2. */
+ Q_ASSERT(a1);
+ Q_ASSERT(a2);
+ Q_ASSERT(comp);
+
+ return compare(a1->evaluateSingleton(context),
+ a2->evaluateSingleton(context),
+ comp,
+ m_operator);
+}
+
+bool GeneralComparison::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it1(m_operand1->evaluateSequence(context));
+ Item item1(it1->next());
+
+ if(!item1)
+ return false;
+
+ const Item::Iterator::Ptr it2(m_operand2->evaluateSequence(context));
+ Item::List cache;
+ Item item2;
+
+ while(true)
+ {
+ item2 = it2->next();
+ if(!item2)
+ break;
+
+ if(generalCompare(item1, item2, context))
+ return true;
+
+ cache.append(item2);
+ }
+
+ while(true)
+ {
+ item1 = it1->next();
+
+ if(!item1)
+ return false;
+
+ const Item::List::const_iterator end(cache.constEnd());
+ Item::List::const_iterator it(cache.constBegin());
+
+ for(; it != end; ++it)
+ if(generalCompare(item1, *it, context))
+ return true;
+ }
+
+ Q_ASSERT(false);
+ return false;
+}
+
+Expression::Ptr GeneralComparison::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ if(ValueComparison::isCaseInsensitiveCompare(m_operand1, m_operand2))
+ useCaseInsensitiveComparator();
+
+ return me;
+}
+
+Expression::Ptr GeneralComparison::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+
+ const ItemType::Ptr t1(m_operand1->staticType()->itemType());
+ const ItemType::Ptr t2(m_operand2->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ }
+
+ if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::xsAnyAtomicType == *t2)
+ return me;
+
+ prepareComparison(fetchGeneralComparator(m_operand1, m_operand2, context));
+
+ if(!m_operand1->staticType()->cardinality().allowsMany() &&
+ !m_operand2->staticType()->cardinality().allowsMany())
+ {
+ /* Rewrite to a ValueComparison whose operands uses typing rules
+ * as for an general comparison(that's what's done above). */
+ return rewrite(Expression::Ptr(new ValueComparison(m_operand1,
+ m_operator,
+ m_operand2))->typeCheck(context, reqType),
+ context);
+ }
+ else
+ return me;
+}
+
+void GeneralComparison::updateType(ItemType::Ptr &type,
+ const Expression::Ptr &source)
+{
+ type = source->staticType()->itemType();
+}
+
+AtomicComparator::Ptr GeneralComparison::fetchGeneralComparator(Expression::Ptr &op1,
+ Expression::Ptr &op2,
+ const ReportContext::Ptr &context) const
+{
+ ItemType::Ptr t1(op1->staticType()->itemType());
+ ItemType::Ptr t2(op2->staticType()->itemType());
+
+ /* a. "If one of the atomic values is an instance of xs:untypedAtomic and
+ * the other is an instance of a numeric type, then the xs:untypedAtomic
+ * value is cast to the type xs:double." */
+ if(BuiltinTypes::numeric->xdtTypeMatches(t1) &&
+ BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2))
+ {
+ op2 = Expression::Ptr(new UntypedAtomicConverter(op2, BuiltinTypes::xsDouble));
+
+ /* The types might have changed, reload. */
+ updateType(t2, op2);
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(t2) &&
+ BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1))
+ {
+ op1 = Expression::Ptr(new UntypedAtomicConverter(op1, BuiltinTypes::xsDouble));
+
+ /* The types might have changed, reload. */
+ updateType(t1, op1);
+ }
+ /* "If XPath 1.0 compatibility mode is true, a general comparison is
+ * evaluated by applying the following rules, in order:
+ * 1. If either operand is a single atomic value that is an instance of
+ * xs:boolean, then the other operand is converted to xs:boolean by taking
+ * its effective boolean value."
+ *
+ * Notably, it's not conversion to boolean, it is EBV extraction.
+ */
+ else if(m_isBackwardsCompat && BuiltinTypes::xsBoolean->xdtTypeMatches(t1))
+ {
+ op2 = Expression::Ptr(new EBVExtractor(op2));
+ updateType(t2, op2);
+ }
+ else if(m_isBackwardsCompat && BuiltinTypes::xsBoolean->xdtTypeMatches(t2))
+ {
+ op1 = Expression::Ptr(new EBVExtractor(op1));
+ updateType(t1, op1);
+ }
+ /* b. "If one of the atomic values is an instance of xs:untypedAtomic and
+ * the other is an instance of xs:untypedAtomic or xs:string, then the
+ * xs:untypedAtomic value (or values) is (are) cast to the type xs:string."
+ *
+ * c. "If one of the atomic values is an instance of xs:untypedAtomic and the
+ * other is not an instance of xs:string, xs:untypedAtomic, or any numeric
+ * type, then the xs:untypedAtomic value is cast to the dynamic type of the
+ * other value." */
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsString->xdtTypeMatches(t2) &&
+ !BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2) &&
+ !BuiltinTypes::xsAnyURI->xdtTypeMatches(t2))
+ {
+ op1 = Expression::Ptr(new UntypedAtomicConverter(op1, t2));
+ updateType(t1, op1);
+ }
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2) &&
+ !BuiltinTypes::xsString->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsAnyURI->xdtTypeMatches(t1))
+ {
+ op2 = Expression::Ptr(new UntypedAtomicConverter(op2, t1));
+ updateType(t2, op2);
+ }
+
+ /* d. "After performing the conversions described above, the atomic
+ * values are compared using one of the value comparison operators
+ * eq, ne, lt, le, gt, or ge, depending on whether the general comparison
+ * operator was =, !=, <, <=, >, or >=. The values have the required
+ * magnitude relationship if and only if the result of this value comparison
+ * is true." */
+
+ return fetchComparator(t1, t2, context);
+}
+
+OptimizationPass::List GeneralComparison::optimizationPasses() const
+{
+ Q_ASSERT(!OptimizationPasses::comparisonPasses.isEmpty());
+ return OptimizationPasses::comparisonPasses;
+}
+
+SequenceType::List GeneralComparison::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ return result;
+}
+
+SequenceType::Ptr GeneralComparison::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr GeneralComparison::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID GeneralComparison::id() const
+{
+ return IDGeneralComparison;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qgeneralcomparison_p.h b/src/xmlpatterns/expr/qgeneralcomparison_p.h
new file mode 100644
index 0000000..cc83e22
--- /dev/null
+++ b/src/xmlpatterns/expr/qgeneralcomparison_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GeneralComparison_H
+#define Patternist_GeneralComparison_H
+
+#include "qatomiccomparator_p.h"
+#include "qpaircontainer_p.h"
+#include "qcomparisonplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's general comparions, such as the <tt>=</tt> operator.
+ *
+ * ComparisonPlatform is inherited with @c protected scope because ComparisonPlatform
+ * must access members of GeneralComparison.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-general-comparisons">XML Path Language
+ * (XPath) 2.0, 3.5.2 General Comparisons</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class GeneralComparison : public PairContainer,
+ public ComparisonPlatform<GeneralComparison,
+ true /* We want to report errors. */,
+ AtomicComparator::AsGeneralComparison>
+ {
+ public:
+ GeneralComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2,
+ const bool isBackwardsCompat = false);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always IDGeneralComparison
+ */
+ virtual ID id() const;
+
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ /**
+ * @returns the operator that this GeneralComparison is using.
+ */
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return m_operator;
+ }
+
+ /**
+ * Overridden to optimize case-insensitive compares.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ static inline void updateType(ItemType::Ptr &type,
+ const Expression::Ptr &source);
+ AtomicComparator::Ptr fetchGeneralComparator(Expression::Ptr &op1,
+ Expression::Ptr &op2,
+ const ReportContext::Ptr &context) const;
+ bool generalCompare(const Item &op1,
+ const Item &op2,
+ const DynamicContext::Ptr &context) const;
+
+ const AtomicComparator::Operator m_operator;
+ const bool m_isBackwardsCompat;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qgenericpredicate.cpp b/src/xmlpatterns/expr/qgenericpredicate.cpp
new file mode 100644
index 0000000..624d17d
--- /dev/null
+++ b/src/xmlpatterns/expr/qgenericpredicate.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloat_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qfirstitempredicate_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qtruthpredicate_p.h"
+
+#include "qgenericpredicate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GenericPredicate::GenericPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate) : PairContainer(sourceExpression,
+ predicate)
+{
+}
+
+Expression::Ptr GenericPredicate::create(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicateExpression,
+ const StaticContext::Ptr &context,
+ const QSourceLocation &location)
+{
+ Q_ASSERT(sourceExpression);
+ Q_ASSERT(predicateExpression);
+ Q_ASSERT(context);
+ const ItemType::Ptr type(predicateExpression->staticType()->itemType());
+
+ if(predicateExpression->is(IDIntegerValue) &&
+ predicateExpression->as<Literal>()->item().as<Numeric>()->toInteger() == 1)
+ { /* Handle [1] */
+ return createFirstItem(sourceExpression);
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(type))
+ { /* A numeric predicate, other than [1]. */
+ /* TODO at somepoint we'll return a specialized expr here, NumericPredicate or so.
+ * Dependency analysis is a bit tricky, since the contained expression can depend on
+ * some loop component. */
+ return Expression::Ptr(new GenericPredicate(sourceExpression, predicateExpression));
+ }
+ else if(*CommonSequenceTypes::Empty == *type)
+ {
+ return EmptySequence::create(predicateExpression.data(), context);
+ }
+ else if(*BuiltinTypes::item == *type ||
+ *BuiltinTypes::xsAnyAtomicType == *type)
+ {
+ /* The type couldn't be narrowed at compile time, so we use
+ * a generic predicate. This check is before the CommonSequenceTypes::EBV check,
+ * because the latter matches these types as well. */
+ return Expression::Ptr(new GenericPredicate(sourceExpression, predicateExpression));
+ }
+ else if(CommonSequenceTypes::EBV->itemType()->xdtTypeMatches(type))
+ {
+ return Expression::Ptr(new TruthPredicate(sourceExpression, predicateExpression));
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("A value of type %1 cannot be a "
+ "predicate. A predicate must have "
+ "either a numeric type or an "
+ "Effective Boolean Value type.")
+ .arg(formatType(context->namePool(),
+ sourceExpression->staticType())),
+ ReportContext::FORG0006, location);
+ return Expression::Ptr(); /* Silence compiler warning. */
+ }
+}
+
+Expression::Ptr GenericPredicate::createFirstItem(const Expression::Ptr &sourceExpression)
+
+{
+ return Expression::Ptr(new FirstItemPredicate(sourceExpression));
+}
+
+Item GenericPredicate::mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand2->evaluateSequence(context));
+ const Item pcateItem(it->next());
+
+ if(!pcateItem)
+ return Item(); /* The predicate evaluated to the empty sequence */
+ else if(pcateItem.isNode())
+ return item;
+ /* Ok, now it must be an AtomicValue */
+ else if(BuiltinTypes::numeric->xdtTypeMatches(pcateItem.type()))
+ { /* It's a positional predicate. */
+ if(it->next())
+ {
+ context->error(QtXmlPatterns::tr("A positional predicate must "
+ "evaluate to a single numeric "
+ "value."),
+ ReportContext::FORG0006, this);
+ return Item();
+ }
+
+ if(Double::isEqual(static_cast<xsDouble>(context->contextPosition()),
+ pcateItem.as<Numeric>()->toDouble()))
+ {
+ return item;
+ }
+ else
+ return Item();
+ }
+ else if(Boolean::evaluateEBV(pcateItem, it, context)) /* It's a truth predicate. */
+ return item;
+ else
+ return Item();
+}
+
+Item::Iterator::Ptr GenericPredicate::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context));
+ const DynamicContext::Ptr newContext(context->createFocus());
+ newContext->setFocusIterator(focus);
+
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ focus,
+ newContext);
+}
+
+Item GenericPredicate::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context));
+ const DynamicContext::Ptr newContext(context->createFocus());
+ newContext->setFocusIterator(focus);
+ return mapToItem(focus->next(), newContext);
+}
+
+SequenceType::List GenericPredicate::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr GenericPredicate::staticType() const
+{
+ const SequenceType::Ptr type(m_operand1->staticType());
+ return makeGenericSequenceType(type->itemType(),
+ type->cardinality() | Cardinality::zeroOrOne());
+}
+
+ExpressionVisitorResult::Ptr GenericPredicate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+ItemType::Ptr GenericPredicate::newFocusType() const
+{
+ return m_operand1->staticType()->itemType();
+}
+
+Expression::Properties GenericPredicate::properties() const
+{
+ return CreatesFocusForLast;
+}
+
+QString GenericPredicate::description() const
+{
+ return QLatin1String("predicate");
+}
+
+Expression::ID GenericPredicate::id() const
+{
+ return IDGenericPredicate;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qgenericpredicate_p.h b/src/xmlpatterns/expr/qgenericpredicate_p.h
new file mode 100644
index 0000000..d48e208
--- /dev/null
+++ b/src/xmlpatterns/expr/qgenericpredicate_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GenericPredicate_H
+#define Patternist_GenericPredicate_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A predicate that can handle all kinds of predicates and
+ * is therefore not very efficient, but can cope with all the tricky scenarios.
+ *
+ * @see FirstItemPredicate
+ * @see TruthPredicate
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class GenericPredicate : public PairContainer
+ {
+ public:
+
+ /**
+ * Creates a predicate expression that filters the items gained
+ * from evaluating @p sourceExpression through the filter @p predicateExpression.
+ *
+ * This function performs type analyzis on the passed expressions, and may
+ * return more specialized expressions depending on the analyzis.
+ *
+ * If @p predicateExpression is an invalid predicate, an error is issued
+ * via the @p context.
+ */
+ static Expression::Ptr create(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicateExpression,
+ const StaticContext::Ptr &context,
+ const QSourceLocation &location);
+
+ static Expression::Ptr createFirstItem(const Expression::Ptr &sourceExpression);
+
+ /**
+ * Creates a source iterator which is passed to the ItemMappingIterator
+ * and the Focus. The ItemMappingIterator modifies it with
+ * its QAbstractXmlForwardIterator::next() calls, and since the Focus references the same QAbstractXmlForwardIterator,
+ * the focus is automatically moved.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Doesn't return the first item from calling evaluateSequence(), but does the mapping
+ * manually. This avoid allocating an ItemMappingIterator.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ inline Item mapToItem(const Item &subject,
+ const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ /**
+ * @returns always CreatesFocusForLast.
+ */
+ virtual Properties properties() const;
+
+ virtual QString description() const;
+
+ protected:
+
+ /**
+ * Creates a GenericPredicate which filters the items from the @p sourceExpression
+ * through @p predicate.
+ *
+ * This constructor is protected. The proper way to create predicates is via the static
+ * create() function.
+ */
+ GenericPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate);
+
+ /**
+ * @returns the ItemType of the first operand's staticType().
+ */
+ virtual ItemType::Ptr newFocusType() const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const GenericPredicate> ConstPtr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qifthenclause.cpp b/src/xmlpatterns/expr/qifthenclause.cpp
new file mode 100644
index 0000000..cd9cbc3
--- /dev/null
+++ b/src/xmlpatterns/expr/qifthenclause.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qoptimizationpasses_p.h"
+
+#include "qifthenclause_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+IfThenClause::IfThenClause(const Expression::Ptr &test,
+ const Expression::Ptr &then,
+ const Expression::Ptr &el) : TripleContainer(test, then, el)
+{
+}
+
+Item::Iterator::Ptr IfThenClause::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context)
+ ? m_operand2->evaluateSequence(context)
+ : m_operand3->evaluateSequence(context);
+}
+
+Item IfThenClause::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context)
+ ? m_operand2->evaluateSingleton(context)
+ : m_operand3->evaluateSingleton(context);
+}
+
+bool IfThenClause::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context)
+ ? m_operand2->evaluateEBV(context)
+ : m_operand3->evaluateEBV(context);
+}
+
+void IfThenClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ if(m_operand1->evaluateEBV(context))
+ m_operand2->evaluateToSequenceReceiver(context);
+ else
+ m_operand3->evaluateToSequenceReceiver(context);
+}
+
+Expression::Ptr IfThenClause::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(TripleContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ /* All operands mustn't be evaluated in order for const folding to
+ * be possible. Let's see how far we get. */
+
+ if(m_operand1->isEvaluated())
+ {
+ if(m_operand1->evaluateEBV(context->dynamicContext()))
+ return m_operand2;
+ else
+ return m_operand3;
+ }
+ else
+ return me;
+}
+
+QList<QExplicitlySharedDataPointer<OptimizationPass> > IfThenClause::optimizationPasses() const
+{
+ return OptimizationPasses::ifThenPasses;
+}
+
+SequenceType::List IfThenClause::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::EBV);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr IfThenClause::staticType() const
+{
+ const SequenceType::Ptr t1(m_operand2->staticType());
+ const SequenceType::Ptr t2(m_operand3->staticType());
+
+ return makeGenericSequenceType(t1->itemType() | t2->itemType(),
+ t1->cardinality() | t2->cardinality());
+}
+
+ExpressionVisitorResult::Ptr IfThenClause::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID IfThenClause::id() const
+{
+ return IDIfThenClause;
+}
+
+/*
+Expression::Properties IfThenClause::properties() const
+{
+ return m_operand1->properties()
+ | m_operand2->properties()
+ | m_operand3->properties()
+ & ( Expression::RequiresFocus
+ | Expression::IsEvaluated
+ | Expression::DisableElimination);
+}
+*/
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qifthenclause_p.h b/src/xmlpatterns/expr/qifthenclause_p.h
new file mode 100644
index 0000000..e24d5d0
--- /dev/null
+++ b/src/xmlpatterns/expr/qifthenclause_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_IfThenClause_H
+#define Patternist_IfThenClause_H
+
+#include "qtriplecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's conditional expression <tt>if([expr]) then [expr] else [expr]</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-conditionals">XML Path Language (XPath) 2.0,
+ * 3.8 Conditional Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class IfThenClause : public TripleContainer
+ {
+ public:
+ IfThenClause(const Expression::Ptr &test,
+ const Expression::Ptr &then,
+ const Expression::Ptr &el);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ /**
+ * @returns IDIfThenClause
+ */
+ virtual ID id() const;
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+ //virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qinstanceof.cpp b/src/xmlpatterns/expr/qinstanceof.cpp
new file mode 100644
index 0000000..8e6e5ce
--- /dev/null
+++ b/src/xmlpatterns/expr/qinstanceof.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qinstanceof_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+InstanceOf::InstanceOf(const Expression::Ptr &operand,
+ const SequenceType::Ptr &tType) : SingleContainer(operand)
+ , m_targetType(tType)
+{
+ Q_ASSERT(m_targetType);
+}
+
+bool InstanceOf::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ Item item(it->next());
+ unsigned int count = 1;
+
+ if(!item)
+ return m_targetType->cardinality().allowsEmpty();
+
+ do
+ {
+ if(!m_targetType->itemType()->itemMatches(item))
+ return false;
+
+ if(count == 2 && !m_targetType->cardinality().allowsMany())
+ return false;
+
+ item = it->next();
+ ++count;
+ } while(item);
+
+ return true;
+}
+
+Expression::Ptr InstanceOf::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me != this || m_operand->has(DisableTypingDeduction))
+ return me;
+
+ const SequenceType::Ptr opType(m_operand->staticType());
+ const ItemType::Ptr targetType(m_targetType->itemType());
+ const ItemType::Ptr operandType(opType->itemType());
+
+ if(m_targetType->cardinality().isMatch(opType->cardinality()))
+ {
+ if(*operandType == *CommonSequenceTypes::Empty || targetType->xdtTypeMatches(operandType))
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else if(!operandType->xdtTypeMatches(targetType))
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ }
+ /* Optimization: rule out the case where instance of will always fail. */
+
+ return me;
+}
+
+SequenceType::Ptr InstanceOf::targetType() const
+{
+ return m_targetType;
+}
+
+SequenceType::Ptr InstanceOf::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+SequenceType::List InstanceOf::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr InstanceOf::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qinstanceof_p.h b/src/xmlpatterns/expr/qinstanceof_p.h
new file mode 100644
index 0000000..d3da026
--- /dev/null
+++ b/src/xmlpatterns/expr/qinstanceof_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_InstanceOf_H
+#define Patternist_InstanceOf_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's <tt>instance of</tt> expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-instance-of">XML Path Language (XPath) 2.0,
+ * 3.10.1 Instance Of</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT InstanceOf : public SingleContainer
+ {
+ public:
+
+ InstanceOf(const Expression::Ptr &operand,
+ const SequenceType::Ptr &targetType);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns the SequenceType that this <tt>instance of</tt> Expression
+ * is testing its operand against.
+ */
+ SequenceType::Ptr targetType() const;
+
+ private:
+ const SequenceType::Ptr m_targetType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qletclause.cpp b/src/xmlpatterns/expr/qletclause.cpp
new file mode 100644
index 0000000..d3e939b
--- /dev/null
+++ b/src/xmlpatterns/expr/qletclause.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qdynamiccontextstore_p.h"
+#include "qliteral_p.h"
+
+#include "qletclause_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+LetClause::LetClause(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const VariableDeclaration::Ptr &decl) : PairContainer(operand1, operand2)
+ , m_varDecl(decl)
+{
+ Q_ASSERT(m_varDecl);
+}
+
+DynamicContext::Ptr LetClause::bindVariable(const DynamicContext::Ptr &context) const
+{
+ context->setExpressionVariable(m_varDecl->slot, Expression::Ptr(new DynamicContextStore(m_operand1, context)));
+ return context;
+}
+
+Item::Iterator::Ptr LetClause::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_operand2->evaluateSequence(bindVariable(context));
+}
+
+Item LetClause::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand2->evaluateSingleton(bindVariable(context));
+}
+
+bool LetClause::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand2->evaluateEBV(bindVariable(context));
+}
+
+void LetClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ m_operand2->evaluateToSequenceReceiver(bindVariable(context));
+}
+
+Expression::Ptr LetClause::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* Consider the following query:
+ *
+ * <tt>let $d := \<child type=""/>
+ * return $d//\*[let $i := @type
+ * return $d//\*[$i]]</tt>
+ *
+ * The node test <tt>@type</tt> is referenced from two different places,
+ * where each reference have a different focus. So, in the case of that the source
+ * uses the focus, we need to use a DynamicContextStore to ensure the variable
+ * is always evaluated with the correct focus, regardless of where it is referenced
+ * from.
+ *
+ * We miss out a lot of false positives. For instance, the case of where the focus
+ * is identical for everyone. One reason we cannot check this, is that Expression
+ * doesn't know about its parent.
+ */
+ m_varDecl->canSourceRewrite = !m_operand1->deepProperties().testFlag(RequiresFocus);
+
+ if(m_varDecl->canSourceRewrite)
+ return m_operand2->typeCheck(context, reqType);
+ else
+ return PairContainer::typeCheck(context, reqType);
+}
+
+Expression::Properties LetClause::properties() const
+{
+ return m_varDecl->expression()->properties() & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+SequenceType::List LetClause::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr LetClause::staticType() const
+{
+ return m_operand2->staticType();
+}
+
+ExpressionVisitorResult::Ptr LetClause::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID LetClause::id() const
+{
+ return IDLetClause;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qletclause_p.h b/src/xmlpatterns/expr/qletclause_p.h
new file mode 100644
index 0000000..24a7bb1
--- /dev/null
+++ b/src/xmlpatterns/expr/qletclause_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_LetClause_H
+#define Patternist_LetClause_H
+
+#include "qpaircontainer_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents a <tt>let</tt>-clause, but is only used at compile
+ * time.
+ *
+ * LetClause is inserted into the AST tree for the single purpose of
+ * ensuring that the focus is correct for the binding expression. Once
+ * that is done, LetClause sometimes rewrites itself to its
+ * <tt>return</tt> expression, and the ExpressionVariableReference will
+ * handle the evaluation of the variable.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class LetClause : public PairContainer
+ {
+ public:
+ LetClause(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const VariableDeclaration::Ptr &decl);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual Properties properties() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ private:
+ inline DynamicContext::Ptr bindVariable(const DynamicContext::Ptr &context) const;
+
+ const VariableDeclaration::Ptr m_varDecl;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qliteral.cpp b/src/xmlpatterns/expr/qliteral.cpp
new file mode 100644
index 0000000..ac68fe3
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteral.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qliteral_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Literal::Literal(const Item &i) : m_item(i)
+{
+ Q_ASSERT(m_item);
+ Q_ASSERT(m_item.isAtomicValue());
+}
+
+Item Literal::evaluateSingleton(const DynamicContext::Ptr &) const
+{
+ return m_item;
+}
+
+bool Literal::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return Boolean::evaluateEBV(m_item, context);
+}
+
+void Literal::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ context->outputReceiver()->item(m_item);
+}
+
+SequenceType::Ptr Literal::staticType() const
+{
+ return makeGenericSequenceType(m_item.type(), Cardinality::exactlyOne());
+}
+
+ExpressionVisitorResult::Ptr Literal::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID Literal::id() const
+{
+ Q_ASSERT(m_item);
+ Q_ASSERT(m_item.isAtomicValue());
+ const ItemType::Ptr t(m_item.type());
+
+ if(BuiltinTypes::xsBoolean->xdtTypeMatches(t))
+ return IDBooleanValue;
+ else if(BuiltinTypes::xsString->xdtTypeMatches(t) ||
+ BuiltinTypes::xsAnyURI->xdtTypeMatches(t) ||
+ BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t))
+ {
+ return IDStringValue;
+ }
+ else if(BuiltinTypes::xsInteger->xdtTypeMatches(t))
+ return IDIntegerValue;
+ else
+ return IDFloat;
+}
+
+Expression::Properties Literal::properties() const
+{
+ return IsEvaluated;
+}
+
+QString Literal::description() const
+{
+ return m_item.stringValue();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qliteral_p.h b/src/xmlpatterns/expr/qliteral_p.h
new file mode 100644
index 0000000..aec7d53
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteral_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Literal_H
+#define Patternist_Literal_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses an AtomicValue, making it available as an Expression.
+ *
+ * This is not only literals that can be created via the XQuery syntax(strings and numbers), but
+ * all other atomic values, such as <tt>xs:date</tt> or <tt>xs:time</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-literals">XQuery 1.0: An XML Query Language,
+ * 3.1.1 Literals</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Literal : public EmptyContainer
+ {
+ public:
+ /**
+ * Creates a Literal that represents @p item.
+ *
+ * @param item must be non-null and cannot be a QXmlNodeModelIndex.
+ */
+ Literal(const Item &item);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+ virtual QString description() const;
+
+ /**
+ * @returns Expression::DisableElimination and Expression::IsEvaluated
+ */
+ virtual Properties properties() const;
+
+ /**
+ * Declaring the return value of this function a const reference, leads
+ * to crashes in patternistview, for a to me unknown reason.
+ */
+ inline Item item() const
+ {
+ return m_item;
+ }
+
+ private:
+ const Item m_item;
+ };
+
+ /**
+ * @short Creates a Literal that wraps @p item, and returns it.
+ *
+ * This simplifies code. Instead of writing:
+ *
+ * @code
+ * Expression::Ptr(new Literal(item));
+ * @endcode
+ *
+ * One can write:
+ *
+ * @code
+ * wrapLiteral(item);
+ * @endcode
+ *
+ * This function is not declared static, because it breaks the build on
+ * at least aix-xlc-64.
+ *
+ * @relates Literal
+ */
+ inline Expression::Ptr wrapLiteral(const Item &item,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+ {
+ Q_ASSERT(item);
+
+ const Expression::Ptr retval(new Literal(item));
+ context->addLocation(retval.data(), context->locationFor(r));
+
+ return retval;
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qliteralsequence.cpp b/src/xmlpatterns/expr/qliteralsequence.cpp
new file mode 100644
index 0000000..dfd0fd6
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteralsequence.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qliteralsequence_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+LiteralSequence::LiteralSequence(const Item::List &list) : m_list(list)
+{
+ Q_ASSERT(list.size() >= 2);
+}
+
+Item::Iterator::Ptr LiteralSequence::evaluateSequence(const DynamicContext::Ptr &) const
+{
+ return makeListIterator(m_list);
+}
+
+SequenceType::Ptr LiteralSequence::staticType() const
+{
+ const Item::List::const_iterator end(m_list.constEnd());
+ Item::List::const_iterator it(m_list.constBegin());
+
+ /* Load the first item. */
+ ItemType::Ptr t((*it).type());
+ ++it;
+
+ for(; end != it; ++it)
+ t |= (*it).type();
+
+ return makeGenericSequenceType(t, Cardinality::fromCount(m_list.size()));
+}
+
+ExpressionVisitorResult::Ptr LiteralSequence::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID LiteralSequence::id() const
+{
+ return IDExpressionSequence;
+}
+
+Expression::Properties LiteralSequence::properties() const
+{
+ return IsEvaluated;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qliteralsequence_p.h b/src/xmlpatterns/expr/qliteralsequence_p.h
new file mode 100644
index 0000000..6699ce0
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteralsequence_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_LiteralSequence_H
+#define Patternist_LiteralSequence_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses a sequence of atomic values, making it available as an Expression.
+ *
+ * This is not only literals that can be created via the XQuery syntax(strings and numbers), but
+ * all other atomic values, such as <tt>xs:date</tt> or <tt>xs:time</tt>. It is not guaranteed
+ * that consecutive atomic values are represented in a LiteralSequence.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-literals">XQuery 1.0: An XML Query Language,
+ * 3.1.1 Literals</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class LiteralSequence : public EmptyContainer
+ {
+ public:
+ /**
+ * Creates a LiteralSequence that represents @p item.
+ *
+ * @param list the list of item. No entry may be @c null. The list
+ * must at least be two entries large.
+ */
+ LiteralSequence(const Item::List &list);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual ID id() const;
+
+ virtual Properties properties() const;
+
+ private:
+ const Item::List m_list;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qnamespaceconstructor.cpp b/src/xmlpatterns/expr/qnamespaceconstructor.cpp
new file mode 100644
index 0000000..c6838ee
--- /dev/null
+++ b/src/xmlpatterns/expr/qnamespaceconstructor.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qnamespaceconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamespaceConstructor::NamespaceConstructor(const QXmlName nb) : m_binding(nb)
+{
+ Q_ASSERT(!m_binding.isNull());
+}
+
+void NamespaceConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ context->outputReceiver()->namespaceBinding(m_binding);
+}
+
+SequenceType::Ptr NamespaceConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneAttribute;
+}
+
+SequenceType::List NamespaceConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ return result;
+}
+
+Expression::Properties NamespaceConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr NamespaceConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID NamespaceConstructor::id() const
+{
+ return IDNamespaceConstructor;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qnamespaceconstructor_p.h b/src/xmlpatterns/expr/qnamespaceconstructor_p.h
new file mode 100644
index 0000000..5b73d37
--- /dev/null
+++ b/src/xmlpatterns/expr/qnamespaceconstructor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamespaceConstructor_H
+#define Patternist_NamespaceConstructor_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a namespace on an element, and naturally only appears
+ * as a child of ElementConstructor.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class NamespaceConstructor : public EmptyContainer
+ {
+ public:
+ NamespaceConstructor(const QXmlName nb);
+
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ExactlyOneString instance.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * The static type is exactly one attribute node. It's unclear what
+ * affects the static type has, but specifying anything else could lead
+ * to complications wrt. node order, XQTY0024. Of course, it's not
+ * conceptually correct, since a namespace node isn't an attribute
+ * node.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Properties properties() const;
+
+ inline const QXmlName &namespaceBinding() const
+ {
+ return m_binding;
+ }
+
+ virtual ID id() const;
+ private:
+ const QXmlName m_binding;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qncnameconstructor.cpp b/src/xmlpatterns/expr/qncnameconstructor.cpp
new file mode 100644
index 0000000..b1d2739
--- /dev/null
+++ b/src/xmlpatterns/expr/qncnameconstructor.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qatomicstring_p.h"
+
+#include "qncnameconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NCNameConstructor::NCNameConstructor(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item NCNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ /* Apply the whitespace facet for when casting to xs:NCName. */
+ const QString lexNCName(m_operand->evaluateSingleton(context).stringValue().trimmed());
+
+ validateTargetName<DynamicContext::Ptr,
+ ReportContext::XQDY0064,
+ ReportContext::XQDY0041>(lexNCName,
+ context,
+ this);
+ return AtomicString::fromValue(lexNCName);
+}
+
+Expression::Ptr NCNameConstructor::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(BuiltinTypes::xsNCName->xdtTypeMatches(m_operand->staticType()->itemType()))
+ return m_operand->typeCheck(context, reqType);
+ else
+ return SingleContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr NCNameConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneString;
+}
+
+SequenceType::List NCNameConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr NCNameConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qncnameconstructor_p.h b/src/xmlpatterns/expr/qncnameconstructor_p.h
new file mode 100644
index 0000000..02163c5
--- /dev/null
+++ b/src/xmlpatterns/expr/qncnameconstructor_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NCNameConstructor_H
+#define Patternist_NCNameConstructor_H
+
+#include "qsinglecontainer_p.h"
+#include "qpatternistlocale_p.h"
+#include "private/qxmlutils_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Ensures the lexical space of the string value of the Item returned
+ * from its child Expression is an NCName.
+ *
+ * @note It doesn't actually construct an @c xs:NCName. It only ensures the lexical
+ * space is an @c NCName. The atomic value can be of any string type, such as @c xs:untypedAtomic
+ * of @c xs:string.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class NCNameConstructor : public SingleContainer
+ {
+ public:
+
+ NCNameConstructor(const Expression::Ptr &source);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Validates @p lexicalNCName as a processing instruction's target
+ * name, and raise an error if it's not an @c NCName.
+ */
+ template<typename TReportContext,
+ const ReportContext::ErrorCode NameIsXML,
+ const ReportContext::ErrorCode LexicallyInvalid>
+ static inline
+ void validateTargetName(const QString &lexicalNCName,
+ const TReportContext &context,
+ const SourceLocationReflection *const r);
+ private:
+
+ /**
+ * This translation string is put here in order to avoid duplicate messages and
+ * hence reduce work for translators and increase consistency.
+ */
+ static
+ const QString nameIsXML(const QString &lexTarget)
+ {
+ return QtXmlPatterns::tr("The target name in a processing instruction "
+ "cannot be %1 in any combination of upper "
+ "and lower case. Therefore, %2 is invalid.")
+ .arg(formatKeyword("xml"), formatKeyword(lexTarget));
+ }
+ };
+
+ template<typename TReportContext,
+ const ReportContext::ErrorCode NameIsXML,
+ const ReportContext::ErrorCode LexicallyInvalid>
+ inline
+ void NCNameConstructor::validateTargetName(const QString &lexicalTarget,
+ const TReportContext &context,
+ const SourceLocationReflection *const r)
+ {
+ Q_ASSERT(context);
+
+ if(QXmlUtils::isNCName(lexicalTarget))
+ {
+ if(QString::compare(QLatin1String("xml"), lexicalTarget, Qt::CaseInsensitive) == 0)
+ context->error(nameIsXML(lexicalTarget), NameIsXML, r);
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("%1 is not a valid target name in "
+ "a processing instruction. It "
+ "must be a %2 value, e.g. %3.")
+ .arg(formatKeyword(lexicalTarget))
+ .arg(formatType(context->namePool(),
+ BuiltinTypes::xsNCName))
+ .arg(formatKeyword("my-name.123")),
+ LexicallyInvalid,
+ r);
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qnodecomparison.cpp b/src/xmlpatterns/expr/qnodecomparison.cpp
new file mode 100644
index 0000000..ba262fd
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodecomparison.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qemptysequence_p.h"
+#include "qinteger_p.h"
+#include "qschemanumeric_p.h"
+#include "qrangeiterator_p.h"
+
+#include "qnodecomparison_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NodeComparison::NodeComparison(const Expression::Ptr &operand1,
+ const QXmlNodeModelIndex::DocumentOrder op,
+ const Expression::Ptr &operand2)
+ : PairContainer(operand1, operand2)
+ , m_op(op)
+{
+ Q_ASSERT(op == QXmlNodeModelIndex::Precedes ||
+ op == QXmlNodeModelIndex::Follows ||
+ op == QXmlNodeModelIndex::Is);
+}
+
+Item NodeComparison::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ switch(evaluate(context))
+ {
+ case True:
+ return CommonValues::BooleanTrue;
+ case False:
+ return CommonValues::BooleanFalse;
+ default:
+ return Item();
+ }
+}
+
+bool NodeComparison::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ switch(evaluate(context))
+ {
+ case True:
+ return true;
+ default:
+ /* We include the empty sequence here. */
+ return false;
+ }
+}
+
+NodeComparison::Result NodeComparison::evaluate(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operand1->evaluateSingleton(context));
+ if(!op1)
+ return Empty;
+
+ const Item op2(m_operand2->evaluateSingleton(context));
+ if(!op2)
+ return Empty;
+
+ /* We just returns an arbitrary value, since there's no order defined for nodes from different
+ * models, except for that the return value must be stable. */
+ if(op1.asNode().model() != op2.asNode().model())
+ return False;
+
+ switch(m_op)
+ {
+ case QXmlNodeModelIndex::Is:
+ return op1.asNode().is(op2.asNode()) ? True : False;
+ case QXmlNodeModelIndex::Precedes:
+ return op1.asNode().compareOrder(op2.asNode()) == QXmlNodeModelIndex::Precedes ? True : False;
+ default:
+ {
+ Q_ASSERT(m_op == QXmlNodeModelIndex::Follows);
+ return op1.asNode().compareOrder(op2.asNode()) == QXmlNodeModelIndex::Follows ? True : False;
+ }
+ }
+}
+
+
+SequenceType::List NodeComparison::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneNode);
+ result.append(CommonSequenceTypes::ZeroOrOneNode);
+ return result;
+}
+
+Expression::Ptr NodeComparison::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ if(me != this)
+ /* We're already rewritten. */
+ return me;
+
+ if(m_operand1->staticType()->cardinality().isEmpty() ||
+ m_operand2->staticType()->cardinality().isEmpty())
+ {
+ // TODO issue a warning in the @p context saying that one of the operands
+ // were empty, and that the expression always result in the empty sequence
+ // (which never is the intent, right?).
+ return EmptySequence::create(this, context);
+ }
+
+ return Expression::Ptr(this);
+}
+
+QString NodeComparison::displayName(const QXmlNodeModelIndex::DocumentOrder op)
+{
+ switch(op)
+ {
+ case QXmlNodeModelIndex::Is:
+ return QLatin1String("is");
+ case QXmlNodeModelIndex::Precedes:
+ return QLatin1String("<<");
+ default:
+ {
+ Q_ASSERT(op == QXmlNodeModelIndex::Follows);
+ return QLatin1String(">>");
+ }
+ }
+}
+
+SequenceType::Ptr NodeComparison::staticType() const
+{
+ if(m_operand1->staticType()->cardinality().allowsEmpty() ||
+ m_operand2->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneBoolean;
+ else
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+QXmlNodeModelIndex::DocumentOrder NodeComparison::operatorID() const
+{
+ return m_op;
+}
+
+ExpressionVisitorResult::Ptr NodeComparison::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qnodecomparison_p.h b/src/xmlpatterns/expr/qnodecomparison_p.h
new file mode 100644
index 0000000..86af0f6
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodecomparison_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NodeComparison_H
+#define Patternist_NodeComparison_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the node comparison operators <tt>\>\></tt>, <tt>\<\<</tt>, and @c is.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-node-comparisons">XML Path Language
+ * (XPath) 2.0, 3.5.3 QXmlNodeModelIndex Comparisons</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT NodeComparison : public PairContainer
+ {
+ public:
+ NodeComparison(const Expression::Ptr &operand1,
+ const QXmlNodeModelIndex::DocumentOrder op,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual QXmlNodeModelIndex::DocumentOrder operatorID() const;
+ /**
+ * If any operator is the empty sequence, the NodeComparison rewrites
+ * into that, since the empty sequence is always the result in that case.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns either CommonSequenceTypes::ZeroOrOneBoolean or
+ * CommonSequenceTypes::ExactlyOneBoolean depending on the static
+ * cardinality of its operands.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Determines the string representation for a node comparison operator.
+ *
+ * @returns
+ * - "<<" if @p op is Precedes
+ * - ">>" if @p op is Follows
+ * - "is" if @p op is Is
+ */
+ static QString displayName(const QXmlNodeModelIndex::DocumentOrder op);
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ private:
+ enum Result
+ {
+ Empty,
+ True,
+ False
+ };
+ inline Result evaluate(const DynamicContext::Ptr &context) const;
+
+ const QXmlNodeModelIndex::DocumentOrder m_op;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qnodesort.cpp b/src/xmlpatterns/expr/qnodesort.cpp
new file mode 100644
index 0000000..171fbc0
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodesort.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdeduplicateiterator_p.h"
+#include "qnodesort_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NodeSortExpression::NodeSortExpression(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+bool NodeSortExpression::lessThanUsingNodeModel(const Item &n1,
+ const Item &n2)
+{
+ Q_ASSERT(n1.isNode());
+ Q_ASSERT(n2.isNode());
+
+ if(n1.asNode().model() == n2.asNode().model())
+ return n1.asNode().compareOrder(n2.asNode()) == QXmlNodeModelIndex::Precedes;
+ else
+ {
+ /* The two nodes are from different trees. The sort order is implementation
+ * defined, but it must be stable.
+ *
+ * We do this by looking at the pointer difference. The value means nothing,
+ * but it is stable, and that's what we're looking for. */
+ return n1.asNode().model() - n2.asNode().model() < 0;
+ }
+}
+
+Item::Iterator::Ptr NodeSortExpression::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT_X(m_operand->staticType()->cardinality().allowsMany(), Q_FUNC_INFO,
+ "It makes no sense to sort a single node.");
+
+ Item::List nodes(m_operand->evaluateSequence(context)->toList());
+
+ if(nodes.isEmpty())
+ return CommonValues::emptyIterator;
+ else if(nodes.first().isAtomicValue())
+ return makeListIterator(nodes);
+ else
+ {
+ qSort(nodes.begin(), nodes.end(), lessThanUsingNodeModel);
+
+ return Item::Iterator::Ptr(new DeduplicateIterator(nodes));
+ }
+}
+
+Expression::Ptr NodeSortExpression::wrapAround(const Expression::Ptr &operand,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(operand);
+ Q_ASSERT(context);
+
+ const Expression::Ptr sort(new NodeSortExpression(operand));
+ context->wrapExpressionWith(operand.data(), sort);
+ return sort;
+}
+
+Expression::Ptr NodeSortExpression::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ /* It make no sense to sort & deduplicate a single node. */
+ if(m_operand->staticType()->cardinality().allowsMany())
+ return me;
+ else
+ return m_operand;
+}
+
+SequenceType::Ptr NodeSortExpression::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List NodeSortExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr
+NodeSortExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties NodeSortExpression::properties() const
+{
+ /* The reason we disable elimination is that the assert for sorting a
+ * single node in evaluateSequence() triggers unless our compress() routine
+ * has been run. Anyhow, it's not that we would manage to write away anyway,
+ * since the node source in most(all?) cases prevents it.
+ */
+ return AffectsOrderOnly | DisableElimination;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qnodesort_p.h b/src/xmlpatterns/expr/qnodesort_p.h
new file mode 100644
index 0000000..850023b
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodesort_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NodeSortExpression_H
+#define Patternist_NodeSortExpression_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short De-duplicates and sorts in document order the content that its
+ * operand returns.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class NodeSortExpression : public SingleContainer
+ {
+ public:
+ NodeSortExpression(const Expression::Ptr &operand);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+
+ /**
+ * Ensures that result delivered from @p operand, is in document order.
+ */
+ static Expression::Ptr wrapAround(const Expression::Ptr &operand,
+ const StaticContext::Ptr &context);
+
+ private:
+ static inline bool lessThanUsingNodeModel(const Item &n1,
+ const Item &n2);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoperandsiterator_p.h b/src/xmlpatterns/expr/qoperandsiterator_p.h
new file mode 100644
index 0000000..9986ef2
--- /dev/null
+++ b/src/xmlpatterns/expr/qoperandsiterator_p.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_OperandsIterator_H
+#define Patternist_OperandsIterator_H
+
+#include <QPair>
+#include <QStack>
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class that iterates a tree of Expression instances. It
+ * is not a sub-class of QAbstractXmlForwardIterator.
+ *
+ * The OperandsIterator delivers all Expression instances that are children at any
+ * depth of the Expression passed in the constructor.
+ * The order is delivered in a defined way, from left to right and depth
+ * first.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class OperandsIterator
+ {
+ /**
+ * The second value, the int, is the current position in the first.
+ */
+ typedef QPair<Expression::List, int> Level;
+
+ public:
+ enum TreatParent
+ {
+ ExcludeParent,
+ IncludeParent
+ };
+
+ /**
+ * if @p treatParent is @c IncludeParent, @p start is excluded.
+ *
+ * @p start must be a valid Expression.
+ */
+ inline OperandsIterator(const Expression::Ptr &start,
+ const TreatParent treatParent)
+ {
+ Q_ASSERT(start);
+ if(treatParent == IncludeParent)
+ {
+ Expression::List l;
+ l.append(start);
+ m_exprs.push(qMakePair(l, -1));
+ }
+
+ m_exprs.push(qMakePair(start->operands(), -1));
+ }
+
+ /**
+ * @short Returns the current Expression and advances the iterator.
+ *
+ * If the end has been reached, a default constructed pointer is
+ * returned.
+ *
+ * We intentionally return by reference.
+ */
+ inline Expression::Ptr next()
+ {
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+
+ Level &lvl = m_exprs.top();
+ ++lvl.second;
+
+ if(lvl.second == lvl.first.size())
+ {
+ /* Resume iteration above us. */
+ m_exprs.pop();
+
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+
+ while(true)
+ {
+ Level &previous = m_exprs.top();
+ ++previous.second;
+
+ if(previous.second < previous.first.count())
+ {
+ const Expression::Ptr &op = previous.first.at(previous.second);
+ m_exprs.push(qMakePair(op->operands(), -1));
+ return op;
+ }
+ else
+ {
+ // We have already reached the end of this level.
+ m_exprs.pop();
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+ }
+ }
+ }
+ else
+ {
+ const Expression::Ptr &op = lvl.first.at(lvl.second);
+ m_exprs.push(qMakePair(op->operands(), -1));
+ return op;
+ }
+ }
+
+ /**
+ * Advances this iterator by the current expression and its operands.
+ */
+ Expression::Ptr skipOperands()
+ {
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+
+ Level &lvl = m_exprs.top();
+ ++lvl.second;
+
+ if(lvl.second == lvl.first.size())
+ {
+ /* We've reached the end of this level, at least. */
+ m_exprs.pop();
+ }
+
+ return next();
+ }
+
+ private:
+ Q_DISABLE_COPY(OperandsIterator)
+
+ QStack<Level> m_exprs;
+ };
+}
+
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoptimizationpasses.cpp b/src/xmlpatterns/expr/qoptimizationpasses.cpp
new file mode 100644
index 0000000..d970483
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizationpasses.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qoptimizerblocks_p.h"
+
+#include "qoptimizationpasses_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+OptimizationPass::List OptimizationPasses::comparisonPasses;
+OptimizationPass::List OptimizationPasses::forPasses;
+OptimizationPass::List OptimizationPasses::ifThenPasses;
+OptimizationPass::List OptimizationPasses::notFN;
+
+void OptimizationPasses::Coordinator::init()
+{
+ static bool isInitialized = false; // STATIC DATA
+
+ if(isInitialized)
+ return;
+
+ isInitialized = true;
+
+ /* Note, below is many of the building blocks re-used in several passes
+ * in order to reduce memory use. Thus, when changing one building block
+ * it potentially affects many passes. */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) ge 1" into "exists(<expr>)" */
+ OptimizationPass::ExpressionMarker firstFirstChild;
+ firstFirstChild.append(0);
+ firstFirstChild.append(0);
+
+ ExpressionIdentifier::List geOpIDs;
+ const ExpressionIdentifier::Ptr countFN(new ByIDIdentifier(Expression::IDCountFN));
+ geOpIDs.append(countFN);
+ geOpIDs.append(ExpressionIdentifier::Ptr(new IntegerIdentifier(1)));
+
+ QVector<Expression::ID> geMatcher;
+ geMatcher.append(Expression::IDValueComparison);
+ geMatcher.append(Expression::IDGeneralComparison);
+
+ const ExpressionIdentifier::Ptr ge(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorGreaterOrEqual));
+
+ const ExpressionCreator::Ptr existsFN(new ByIDCreator(Expression::IDExistsFN));
+ const OptimizationPass::Ptr geToExists(new OptimizationPass(ge, geOpIDs, firstFirstChild, existsFN));
+ comparisonPasses.append(geToExists);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) gt 0" into "exists(<expr>)" */
+ ExpressionIdentifier::List countAndIntZero;
+ countAndIntZero.append(countFN);
+ const ExpressionIdentifier::Ptr zeroInteger(new IntegerIdentifier(0));
+ countAndIntZero.append(zeroInteger);
+
+ const ExpressionIdentifier::Ptr gt(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorGreaterThan));
+
+ const OptimizationPass::Ptr gtToExists(new OptimizationPass(gt, countAndIntZero,
+ firstFirstChild, existsFN));
+ comparisonPasses.append(gtToExists);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) ne 0" into "exists(<expr>)" */
+
+ const ExpressionIdentifier::Ptr ne(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorNotEqual));
+ const OptimizationPass::Ptr neToExists(new OptimizationPass(ne, countAndIntZero, firstFirstChild,
+ existsFN,
+ OptimizationPass::AnyOrder));
+ comparisonPasses.append(neToExists);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) eq 0" into "empty(<expr>)" */
+ ExpressionIdentifier::List eqOpIDs;
+ eqOpIDs.append(countFN);
+ eqOpIDs.append(zeroInteger);
+ const ExpressionCreator::Ptr emptyFN(new ByIDCreator(Expression::IDEmptyFN));
+ const ExpressionIdentifier::Ptr eq(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorEqual));
+ const OptimizationPass::Ptr eqToEmpty(new OptimizationPass(eq, eqOpIDs, firstFirstChild,
+ emptyFN,
+ OptimizationPass::AnyOrder));
+ comparisonPasses.append(eqToEmpty);
+
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "for $var in <expr> return $var" into "<expr>" */
+ ExpressionIdentifier::List forOps;
+ OptimizationPass::ExpressionMarker firstChild;
+ firstChild.append(0);
+
+ forOps.append(ExpressionIdentifier::Ptr());
+ forOps.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDRangeVariableReference)));
+ const OptimizationPass::Ptr simplifyFor(new OptimizationPass(ExpressionIdentifier::Ptr(), forOps,
+ firstChild, ExpressionCreator::Ptr()));
+ forPasses.append(simplifyFor);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "if(<expr>) then true() else false()" to "<expr>" */
+ OptimizationPass::ExpressionMarker marker;
+ marker.append(0);
+
+ ExpressionIdentifier::List opIDs;
+ opIDs.append(ExpressionIdentifier::Ptr(new BySequenceTypeIdentifier(
+ CommonSequenceTypes::ExactlyOneBoolean)));
+ opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(true)));
+ opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(false)));
+
+ const OptimizationPass::Ptr pass(new OptimizationPass(ExpressionIdentifier::Ptr(), opIDs, marker));
+ ifThenPasses.append(pass);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "not(exists(X))" into "empty(X)" */
+ ExpressionIdentifier::List idExistsFN;
+ idExistsFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDExistsFN)));
+
+ notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(),
+ idExistsFN,
+ firstFirstChild,
+ emptyFN)));
+
+ /* Rewrite "not(empty(X))" into "exists(X)" */
+ ExpressionIdentifier::List idEmptyFN;
+ idEmptyFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDEmptyFN)));
+
+ notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(),
+ idEmptyFN,
+ firstFirstChild,
+ existsFN)));
+ /* ****************************************************** */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qoptimizationpasses_p.h b/src/xmlpatterns/expr/qoptimizationpasses_p.h
new file mode 100644
index 0000000..6f10572
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizationpasses_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_OptimizationBlocks_H
+#define Patternist_OptimizationBlocks_H
+
+#include "qatomiccomparator_p.h"
+#include "qexpression_p.h"
+#include "qoptimizerframework_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains a set of common OptimizerPass instances.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ namespace OptimizationPasses
+ {
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>count([expr]) ne 0</tt> into <tt>exists([expr])</tt>
+ * - <tt>count([expr]) != 0</tt> into <tt>exists([expr])</tt>
+ * - <tt>0 ne count([expr])</tt> into <tt>exists([expr])</tt>
+ * - <tt>0 != count([expr])</tt> into <tt>exists([expr])</tt>
+ * - <tt>count([expr]) eq 0</tt> into <tt>empty([expr])</tt>
+ * - <tt>count([expr]) = 0</tt> into <tt>empty([expr])</tt>
+ * - <tt>0 eq count([expr])</tt> into <tt>empty([expr])</tt>
+ * - <tt>0 = count([expr])</tt> into <tt>empty([expr])</tt>
+ * - <tt>count([expr]) ge 1</tt> into <tt>exists([expr])</tt>
+ * - <tt>count([expr]) >= 1</tt> into <tt>exists([expr])</tt>
+ */
+ extern OptimizationPass::List comparisonPasses;
+
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>for $var in [expr] return $var</tt> into <tt>[expr]</tt>
+ */
+ extern OptimizationPass::List forPasses;
+
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>if([expr of type xs:boolean]) then true() else false()</tt>
+ * into <tt>[expr of type xs:boolean]</tt>
+ */
+ extern OptimizationPass::List ifThenPasses;
+
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>fn:not(fn:exists([expr]))</tt> into <tt>fn:empty([expr])</tt>
+ * - <tt>fn:not(fn:empty([expr]))</tt> into <tt>fn:exists([expr])</tt>
+ */
+ extern OptimizationPass::List notFN;
+
+ /**
+ * Initializes the data members in the OptimizationPasses namespace.
+ *
+ * This class is not supposed to be instantiated, but to be used via its init()
+ * function. In fact, this class cannot be instantiated.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ */
+ class Coordinator
+ {
+ public:
+ /**
+ * Initializes the members in the OptimizationPasses namespace.
+ */
+ static void init();
+
+ private:
+ Q_DISABLE_COPY(Coordinator)
+ inline Coordinator();
+ };
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoptimizerblocks.cpp b/src/xmlpatterns/expr/qoptimizerblocks.cpp
new file mode 100644
index 0000000..511faae
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerblocks.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonnamespaces_p.h"
+
+#include "qcommonsequencetypes_p.h"
+#include "qfunctionfactory_p.h"
+#include "qgeneralcomparison_p.h"
+#include "qliteral_p.h"
+#include "qschemanumeric_p.h"
+#include "qvaluecomparison_p.h"
+
+#include "qoptimizerblocks_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ByIDIdentifier::ByIDIdentifier(const Expression::ID id) : m_id(id)
+{
+}
+
+bool ByIDIdentifier::matches(const Expression::Ptr &expr) const
+{
+ return expr->is(m_id);
+}
+
+ComparisonIdentifier::ComparisonIdentifier(const QVector<Expression::ID> hosts,
+ const AtomicComparator::Operator op) : m_hosts(hosts),
+ m_op(op)
+{
+}
+
+bool ComparisonIdentifier::matches(const Expression::Ptr &e) const
+{
+ const Expression::ID eID = e->id();
+
+ if(eID == Expression::IDGeneralComparison)
+ {
+ if(m_hosts.contains(Expression::IDGeneralComparison))
+ return e->as<GeneralComparison>()->operatorID() == m_op;
+ else
+ return false;
+ }
+ else if(eID == Expression::IDValueComparison)
+ {
+ if(m_hosts.contains(Expression::IDValueComparison))
+ return e->as<ValueComparison>()->operatorID() == m_op;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+BySequenceTypeIdentifier::BySequenceTypeIdentifier(const SequenceType::Ptr &seqType) : m_seqType(seqType)
+{
+ Q_ASSERT(seqType);
+}
+
+bool BySequenceTypeIdentifier::matches(const Expression::Ptr &expr) const
+{
+ const SequenceType::Ptr t(expr->staticType());
+
+ return m_seqType->itemType()->xdtTypeMatches(t->itemType())
+ &&
+ m_seqType->cardinality().isMatch(t->cardinality());
+}
+
+IntegerIdentifier::IntegerIdentifier(const xsInteger num) : m_num(num)
+{
+}
+
+bool IntegerIdentifier::matches(const Expression::Ptr &expr) const
+{
+ return expr->is(Expression::IDIntegerValue) &&
+ expr->as<Literal>()->item().as<Numeric>()->toInteger() == m_num;
+}
+
+BooleanIdentifier::BooleanIdentifier(const bool value) : m_value(value)
+{
+}
+
+bool BooleanIdentifier::matches(const Expression::Ptr &expr) const
+{
+ return expr->is(Expression::IDBooleanValue) &&
+ expr->evaluateEBV(DynamicContext::Ptr()) == m_value;
+}
+
+ByIDCreator::ByIDCreator(const Expression::ID id) : m_id(id)
+{
+ Q_ASSERT(id != Expression::IDIgnorableExpression);
+}
+
+Expression::Ptr ByIDCreator::create(const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r) const
+{
+ return create(m_id, operands, context, r);
+}
+
+Expression::Ptr ByIDCreator::create(const Expression::ID id,
+ const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+{
+ Q_ASSERT(context);
+
+ QXmlName::LocalNameCode fnName;
+
+ switch(id)
+ {
+ case Expression::IDExistsFN:
+ {
+ fnName = StandardLocalNames::exists;
+ break;
+ }
+ case Expression::IDEmptyFN:
+ {
+ fnName = StandardLocalNames::empty;
+ break;
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Cannot create an expression of requested type; m_id is wrong.");
+ return Expression::Ptr();
+ }
+ }
+
+ /* The reason we don't simply do 'new ExistsFN()' ourselves, is that all FunctionCall
+ * instances needs their FunctionSignature in order to function, and the FunctionFactories
+ * sets that. */
+ const QXmlName qName(StandardNamespaces::fn, fnName);
+
+ const Expression::Ptr result(context->functionSignatures()->createFunctionCall(qName, operands, context, r));
+ context->wrapExpressionWith(r, result);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qoptimizerblocks_p.h b/src/xmlpatterns/expr/qoptimizerblocks_p.h
new file mode 100644
index 0000000..575e07c
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerblocks_p.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_OptimizerBlocks_H
+#define Patternist_OptimizerBlocks_H
+
+#include "qatomiccomparator_p.h"
+#include "qexpression_p.h"
+#include "qoptimizerframework_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Identifies Expression instances by their Expression::id().
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ByIDIdentifier : public ExpressionIdentifier
+ {
+ public:
+ ByIDIdentifier(const Expression::ID id);
+ virtual bool matches(const Expression::Ptr &expr) const;
+ private:
+ const Expression::ID m_id;
+ };
+
+ /**
+ * @short Identifies Expression instances based on their static type.
+ *
+ * BySequenceTypeIdentifier identifies Expression instances
+ * if their Expression::staticType() matches the requested one,
+ * regardless of whether the Expression is a particular one, such
+ * as AndExpression.
+ *
+ * For example, constructing a BySequenceTypeIdentifier while
+ * passing CommonSequenceTypes::EBV in its constructor will create
+ * a ExpressionIdentifier that returns @c true for a static type with
+ * item type <tt>xs:string</tt>, but returns @c false for a static type involving
+ * <tt>xs:date</tt>.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class BySequenceTypeIdentifier : public ExpressionIdentifier
+ {
+ public:
+ BySequenceTypeIdentifier(const SequenceType::Ptr &seqType);
+
+ /**
+ * @returns @c true, if the static type of @p expr is matches
+ * the SequenceType passed in the BySequenceTypeIdentifier()
+ * constructor, otherwise @c false.
+ */
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const SequenceType::Ptr m_seqType;
+ };
+
+ /**
+ * @short Determines whether an Expression is a value or general comparison or both,
+ * with a certain operator.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ComparisonIdentifier : public ExpressionIdentifier
+ {
+ public:
+
+ /**
+ * @param comparatorHosts the possible parent that may have
+ * the operator. This may be Expression::IDGeneralComparison or
+ * Expression::IDValueComparison. The two values may also be OR'd,
+ * meaning any of them will do.
+ *
+ * @param op the operator that the comparator host must have. For example,
+ * if @p op is AtomicComparator::OperatorGreatorOrEqual this ComparisonIdentifier
+ * will match operator >= in the case of IDGeneralComparison and 'ge' in the
+ * case of IDValueComparison.
+ */
+ ComparisonIdentifier(const QVector<Expression::ID> comparatorHosts,
+ const AtomicComparator::Operator op);
+
+ /**
+ * @returns @c true, if @p expr is a ValueComparison with the operator
+ * passed in ComparisonIdentifier().
+ */
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const QVector<Expression::ID> m_hosts;
+ const AtomicComparator::Operator m_op;
+ };
+
+ /**
+ * @short Matches numeric literals that are of type xs:integer and
+ * has a specific value.
+ *
+ * For example IntegerIdentifier(4) would match the former but
+ * not the latter operand in this expression: "4 + 5".
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class IntegerIdentifier : public ExpressionIdentifier
+ {
+ public:
+ IntegerIdentifier(const xsInteger num);
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const xsInteger m_num;
+ };
+
+ /**
+ * @short Matches boolean literals.
+ *
+ * For example BooleanIdentifier(true) would match the former but
+ * not the latter operand in this expression: "true() + false()".
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class BooleanIdentifier : public ExpressionIdentifier
+ {
+ public:
+ BooleanIdentifier(const bool value);
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const bool m_value;
+ };
+
+ /**
+ * @short Creates a particular Expression instance identified by an Expression::ID.
+ *
+ * For example, if ByIDCreator() is passed Expression::IDCountFN, create()
+ * will return CountFN instances.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ByIDCreator : public ExpressionCreator
+ {
+ public:
+ /**
+ * Creates a ByIDCreator that creates expressions
+ * of the type that @p id identifies.
+ */
+ ByIDCreator(const Expression::ID id);
+ virtual Expression::Ptr create(const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r) const;
+
+ /**
+ * Creates an expression by id @p id with the arguments @p operands.
+ */
+ static Expression::Ptr create(const Expression::ID id,
+ const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r);
+
+ private:
+ const Expression::ID m_id;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoptimizerframework.cpp b/src/xmlpatterns/expr/qoptimizerframework.cpp
new file mode 100644
index 0000000..c9e1991
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerframework.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qoptimizerblocks_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExpressionIdentifier::~ExpressionIdentifier()
+{
+}
+
+ExpressionCreator::~ExpressionCreator()
+{
+}
+
+OptimizationPass::OptimizationPass(const ExpressionIdentifier::Ptr &startID,
+ const ExpressionIdentifier::List &opIDs,
+ const ExpressionMarker &sourceExpr,
+ const ExpressionCreator::Ptr &resultCtor,
+ const OperandsMatchMethod mMethod) : startIdentifier(startID),
+ operandIdentifiers(opIDs),
+ sourceExpression(sourceExpr),
+ resultCreator(resultCtor),
+ operandsMatchMethod(mMethod)
+{
+ Q_ASSERT_X(resultCtor || !sourceExpr.isEmpty(), Q_FUNC_INFO,
+ "Either resultCreator or sourceExpression must be set, otherwise there's "
+ "nothing to rewrite to.");
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qoptimizerframework_p.h b/src/xmlpatterns/expr/qoptimizerframework_p.h
new file mode 100644
index 0000000..a2c9373
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerframework_p.h
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_OptimizerFramework_H
+#define Patternist_OptimizerFramework_H
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A factory for creating Expression instances.
+ *
+ * ExpressionIdentifier is one of the building block of Patternist's
+ * optimizer framework. An ExpressionIdentifier sub-class has
+ * the responsibility of creating the Expression that should be
+ * the result of the optimization.
+ *
+ * This class and sub-classes are never used on their own,
+ * but in cooperation with OptimizationPass.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionCreator : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionCreator> Ptr;
+
+ /**
+ * For some reason this constructor cannot be synthesized.
+ */
+ inline ExpressionCreator()
+ {
+ }
+
+ virtual ~ExpressionCreator();
+ /**
+ * Creates an expression that has @p operands as operands.
+ *
+ * The Expression that is returned is guaranteed, by the caller,
+ * to get a treatment identical to if the expression was created
+ * in an ordinary compilation(via the parser, and so forth). That is,
+ * Expression::typeCheck() and Expression::compress() stages will be
+ * carried out on the returned expression.
+ *
+ * @returns an Expression::Ptr that never is non @c null, valid pointer
+ */
+ virtual Expression::Ptr create(const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const) const = 0;
+
+ private:
+ Q_DISABLE_COPY(ExpressionCreator)
+ };
+
+ /**
+ * @short Abstract base class for all classes that identify Expressions
+ * based on some criteria.
+ *
+ * ExpressionIdentifier is one of the building block of Patternist's
+ * optimizer framework. An ExpressionIdentifier sub-class has
+ * the responsibility of determining whether a particular Expression
+ * is the one an OptimizationPass should apply for.
+ *
+ * This class and sub-classes are never used on their own,
+ * but in cooperation with OptimizationPass.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionIdentifier : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionIdentifier> Ptr;
+ typedef QList<ExpressionIdentifier::Ptr> List;
+
+ /**
+ * For some reason this constructor cannot be synthesized.
+ */
+ inline ExpressionIdentifier()
+ {
+ }
+
+ virtual ~ExpressionIdentifier();
+ /**
+ * @param expr the Expression to be tested. This is guranteed
+ * to always be a non @c null, valid pointer.
+ *
+ * @returns @c true if @p expr matches as according to this ExpressionIdentifier,
+ * otherwise @c false.
+ */
+ virtual bool matches(const Expression::Ptr &expr) const = 0;
+
+ private:
+ Q_DISABLE_COPY(ExpressionIdentifier)
+ };
+
+ /**
+ * @short Describes how a particular optimization pass should be carried out.
+ *
+ * OptimizationPass is essentially a declaration, which describes
+ * how an optimization pass in the form of an AST rewrite should be done,
+ * by describing what that should be rewritten into what how.
+ *
+ * Each OptimizationPass is applied to a "start" Expression. The Expression
+ * that qualifies as a start Expression for the OptimizationPass in question is
+ * determined by startIdentifier; if its ExpressionIdentifier::matches() function
+ * returns @c true, the optimizer continues to apply this OptimizationPass.
+ *
+ * After a start Expression has been found, it is verified if the operands matches
+ * as well by applying the ExpressionIdentifiers in operandIdentifiers to the
+ * start Expression's operands. Similarly, if the operands matches what
+ * operandIdentifiers requires, the optimizer continues to apply this OptimizationPass.
+ *
+ * At this stage, it has been concluded that the OptimizationPass validly applies, and
+ * what now remains is to carry out the actual rewrite. The Expression rewritten
+ * to is the one returned by ExpressionCreator::create(), when invoked via the resultCreator
+ * variable.
+ *
+ * How these components, startIdentifier, operandIdentifiers, sourceExpression,
+ * and resultCreator interacts with one another is described in more detail
+ * in the member documentation as well as the classes they are instances of.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class OptimizationPass : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<OptimizationPass> Ptr;
+ typedef QList<OptimizationPass::Ptr> List;
+
+ enum OperandsMatchMethod
+ {
+ /**
+ * All operands must match in the same order the ExpressionMarkers do.
+ */
+ Sequential = 1,
+
+ /**
+ * Matches if all operands are matched, regardless of their order. This is
+ * useful when an OptimizationPass is matching an Expression that has two operands
+ * and that both of them can appear on the left or right hand as long as it is those
+ * two.
+ *
+ * This comparison method only works when two operands
+ * needs to be matched.
+ */
+ AnyOrder
+ };
+
+ /**
+ * An ExpressionMarker identifies an operand Expression relatively
+ * the start Expression by that each integer identifies a step
+ * in a descending AST walk. For example an ExpressionMarker with
+ * only one entry that is 0(zero), identifies the first operand of the
+ * start Expression. An ExpressionMarker containing 1, 2 in that order
+ * identifies the third operand of the second operand of the start Expression.
+ */
+ typedef QList<qint8> ExpressionMarker;
+
+ /**
+ * Creates an OptimizationPass and sets its public variables
+ * to the corresponding values passed in this constructor.
+ */
+ OptimizationPass(const ExpressionIdentifier::Ptr &startID,
+ const ExpressionIdentifier::List &operandIDs,
+ const ExpressionMarker &sourceExpr,
+ const ExpressionCreator::Ptr &resultCtor = ExpressionCreator::Ptr(),
+ const OperandsMatchMethod matchMethod = Sequential);
+
+ /**
+ * The ExpressionIdentifier that must the Expression this OptimizationPass concerns.
+ *
+ * If this variable is @c null, it means that the start Expression does
+ * not have to match any particular ExpressionIdentifier, but is fine as is.
+ *
+ * One might wonder what the purpose of this startIdentifier is, considering
+ * that what start Expression an OptimizationPass can at all apply to is
+ * naturally determined by what Expression::optimizationPasses() re-implementation that
+ * returns this OptimizationPass. The reason is that in some cases an OptimizationPass
+ * nevertheless doesn't apply. For example, optimizations applying to a ValueComparison
+ * might depend on what operator that is in use.
+ *
+ * May be @c null or point to an ExpressionIdentifier.
+ */
+ const ExpressionIdentifier::Ptr startIdentifier;
+
+ /**
+ * In order for an OptimizationPass to apply, the start Expression's
+ * operands must be matched with this list of ExpressionIdentifier instances.
+ * The first ExpressionIdentifier is applied to the first operand, the second
+ * ExpressionIdentifier to the second operand, and so forth until all operands
+ * have been iterated.
+ *
+ * Entries in this list may be @c null, and those signals that the corresponding
+ * operand is not constrained. For example, if the third ExpressionIdentifier in
+ * the list is @c null, it signals that the third operand may be anykind of expression.
+ *
+ * May be empty or contain an arbitrary amount of objects or @c null pointers.
+ */
+ const ExpressionIdentifier::List operandIdentifiers;
+
+ /**
+ * Identifies the expression that should be part of the new expression
+ * that this OptimizationPass rewrites to. If this list is empty, it
+ * means that the result is not derived from the existing tree, and
+ * that resultCreator will exclusively be used for creating the result
+ * Expression.
+ *
+ * How the ExpressionMarker identifies an Expression is document in
+ * its documentation.
+ *
+ * May be empty.
+ */
+ const ExpressionMarker sourceExpression;
+
+ /**
+ * This is the ExpressionCreator that will be used to create the
+ * Expression which is the result. ExpressionCreator::create()
+ * will be passed as operands the Expression that sourceExpression
+ * specify, if any.
+ *
+ * If this variable is @c null, the result Expression will be the one
+ * sourceExpression identifies.
+ */
+ const ExpressionCreator::Ptr resultCreator;
+
+ const OperandsMatchMethod operandsMatchMethod;
+ private:
+ Q_DISABLE_COPY(OptimizationPass)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qorderby.cpp b/src/xmlpatterns/expr/qorderby.cpp
new file mode 100644
index 0000000..b2fae5a
--- /dev/null
+++ b/src/xmlpatterns/expr/qorderby.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtAlgorithms>
+
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+#include "qschemanumeric_p.h"
+#include "qpatternistlocale_p.h"
+#include "qreturnorderby_p.h"
+#include "qsorttuple_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qorderby_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+OrderBy::OrderBy(const Stability stability,
+ const OrderSpec::Vector &aOrderSpecs,
+ const Expression::Ptr &op,
+ ReturnOrderBy *const returnOrderBy) : SingleContainer(op)
+ , m_stability(stability)
+ , m_orderSpecs(aOrderSpecs)
+ , m_returnOrderBy(returnOrderBy)
+{
+ Q_ASSERT(m_returnOrderBy);
+}
+
+void OrderBy::OrderSpec::prepare(const Expression::Ptr &source,
+ const StaticContext::Ptr &context)
+{
+ m_expr = source;
+ const ItemType::Ptr t(source->staticType()->itemType());
+ prepareComparison(fetchComparator(t, t, context));
+}
+
+/**
+ * @short Functor used by Qt's qSort() and qStableSort(). Used for FLWOR's
+ * <tt>order by</tt> expression.
+ *
+ * This must be in the global namespace, since it is specializing qLess(), which
+ * is in the global namespace. Hence it can't be in QPatternist.
+ */
+template<>
+class qLess<Item::List>
+{
+private:
+
+ static inline bool isNaN(const Item &i)
+ {
+ return BuiltinTypes::xsDouble->xdtTypeMatches(i.type()) &&
+ i.as<Numeric>()->isNaN();
+ }
+
+public:
+ inline qLess(const OrderBy::OrderSpec::Vector &orderspecs,
+ const DynamicContext::Ptr &context) : m_orderSpecs(orderspecs)
+ , m_context(context)
+ {
+ Q_ASSERT(!m_orderSpecs.isEmpty());
+ Q_ASSERT(context);
+ }
+
+ inline bool operator()(const Item &item1, const Item &item2) const
+ {
+ const SortTuple *const s1 = item1.as<SortTuple>();
+ const SortTuple *const s2 = item2.as<SortTuple>();
+
+ const Item::Vector &sortKeys1 = s1->sortKeys();
+ const Item::Vector &sortKeys2 = s2->sortKeys();
+ const int len = sortKeys1.count();
+ Q_ASSERT(sortKeys1.count() == sortKeys2.count());
+
+ for(int i = 0; i < len; ++i)
+ {
+ const Item &i1 = sortKeys1.at(i);
+ const Item &i2 = sortKeys2.at(i);
+ const OrderBy::OrderSpec &orderSpec = m_orderSpecs.at(i);
+
+ if(!i1)
+ {
+ if(i2 && !isNaN(i2))
+ {
+ /* We got ((), item()). */
+ return orderSpec.orderingEmptySequence == StaticContext::Least ? orderSpec.direction == OrderBy::OrderSpec::Ascending
+ : orderSpec.direction != OrderBy::OrderSpec::Ascending;
+ }
+ else
+ return false;
+ }
+
+ if(!i2)
+ {
+ if(i1 && !isNaN(i1))
+ /* We got (item(), ()). */
+ return orderSpec.orderingEmptySequence == StaticContext::Greatest ? orderSpec.direction == OrderBy::OrderSpec::Ascending
+ : orderSpec.direction != OrderBy::OrderSpec::Ascending;
+ else
+ return false;
+ }
+
+ Q_ASSERT(orderSpec.direction == OrderBy::OrderSpec::Ascending ||
+ orderSpec.direction == OrderBy::OrderSpec::Descending);
+ const AtomicComparator::ComparisonResult result = orderSpec.detailedFlexibleCompare(i1, i2, m_context);
+
+ switch(result)
+ {
+ case AtomicComparator::LessThan:
+ return orderSpec.direction == OrderBy::OrderSpec::Ascending;
+ case AtomicComparator::GreaterThan:
+ return orderSpec.direction != OrderBy::OrderSpec::Ascending;
+ case AtomicComparator::Equal:
+ continue;
+ case AtomicComparator::Incomparable:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This code path assume values are always comparable.");
+ }
+ }
+
+ return false;
+ }
+
+private:
+ /* Yes, we store references here. */
+ const OrderBy::OrderSpec::Vector & m_orderSpecs;
+ const DynamicContext::Ptr & m_context;
+};
+
+Item::Iterator::Ptr OrderBy::mapToSequence(const Item &i,
+ const DynamicContext::Ptr &) const
+{
+ return i.as<SortTuple>()->value();
+}
+
+Item::Iterator::Ptr OrderBy::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Item::List tuples(m_operand->evaluateSequence(context)->toList());
+
+ const qLess<Item::List> sorter(m_orderSpecs, context);
+
+ Q_ASSERT(m_stability == StableOrder || m_stability == UnstableOrder);
+
+ /* On one hand we could just disregard stability and always use qStableSort(), but maybe qSort()
+ * is a bit faster? */
+ if(m_stability == StableOrder)
+ qStableSort(tuples.begin(), tuples.end(), sorter);
+ else
+ {
+ Q_ASSERT(m_stability == UnstableOrder);
+ qSort(tuples.begin(), tuples.end(), sorter);
+ }
+
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ makeListIterator(tuples),
+ context);
+}
+
+Expression::Ptr OrderBy::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_returnOrderBy->setStay(true);
+
+ /* It's important we do the typeCheck() before calling OrderSpec::prepare(), since
+ * atomizers must first be inserted. */
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+
+ const Expression::List ops(m_returnOrderBy->operands());
+ const int len = ops.count();
+ Q_ASSERT(ops.count() > 1);
+ Q_ASSERT(m_orderSpecs.count() == ops.count() - 1);
+
+ for(int i = 1; i < len; ++i)
+ m_orderSpecs[i - 1].prepare(ops.at(i), context);
+
+ return me;
+
+ /* It's not meaningful to sort a single item or less, so rewrite ourselves
+ * away if that is the case. This is an optimization. */
+ /* TODO: How do we remove ReturnOrderBy?
+ if(Cardinality::zeroOrOne().isMatch(m_operand->staticType()->cardinality()))
+ return m_operand->typeCheck(context, reqType);
+ else
+ return SingleContainer::typeCheck(context, reqType);
+ */
+}
+
+Expression::Properties OrderBy::properties() const
+{
+ return m_operand->properties() & DisableElimination;
+}
+
+Expression::Ptr OrderBy::compress(const StaticContext::Ptr &context)
+{
+ /* If we only will produce one item, there's no point in sorting. */
+ if(m_operand->staticType()->cardinality().allowsMany())
+ return SingleContainer::compress(context);
+ else
+ {
+ m_returnOrderBy->setStay(false);
+ return m_operand->compress(context);
+ }
+}
+
+SequenceType::Ptr OrderBy::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List OrderBy::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr
+OrderBy::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qorderby_p.h b/src/xmlpatterns/expr/qorderby_p.h
new file mode 100644
index 0000000..332702b
--- /dev/null
+++ b/src/xmlpatterns/expr/qorderby_p.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_OrderBy_H
+#define Patternist_OrderBy_H
+
+#include "qatomiccomparator_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ReturnOrderBy;
+
+ /**
+ * @short Performs the sorting by being a parent to ForClause.
+ *
+ * The child of the ForClause is a ReturnOrderBy expression, which collects
+ * the sort keys and values.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class OrderBy : public SingleContainer
+ {
+ public:
+ enum Stability
+ {
+ StableOrder,
+ UnstableOrder
+ };
+
+ /**
+ * This class is value based.
+ */
+ class OrderSpec : public ComparisonPlatform<OrderBy::OrderSpec,
+ true, /* Yes, issue errors. */
+ AtomicComparator::AsValueComparison>
+ {
+ public:
+ /**
+ * We want this guy to be public.
+ */
+ using ComparisonPlatform<OrderBy::OrderSpec, true, AtomicComparator::AsValueComparison>::detailedFlexibleCompare;
+
+ typedef QVector<OrderSpec> Vector;
+
+ enum Direction
+ {
+ Ascending,
+ Descending
+ };
+
+ /**
+ * @short Default constructor, which is needed by QVector.
+ */
+ inline OrderSpec()
+ {
+ }
+
+ inline OrderSpec(const Direction dir,
+ const StaticContext::OrderingEmptySequence orderingEmpty) : direction(dir),
+ orderingEmptySequence(orderingEmpty)
+ {
+ }
+
+ void prepare(const Expression::Ptr &source,
+ const StaticContext::Ptr &context);
+
+ const SourceLocationReflection *actualReflection() const
+ {
+ return m_expr.data();
+ }
+
+ private:
+ Expression::Ptr m_expr;
+
+ public:
+ /**
+ * We place these afterwards, such that m_expr gets aligned at the
+ * start of the address.
+ */
+ Direction direction;
+
+ StaticContext::OrderingEmptySequence orderingEmptySequence;
+
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return orderingEmptySequence == StaticContext::Least ? AtomicComparator::OperatorLessThanNaNLeast
+ : AtomicComparator::OperatorLessThanNaNGreatest;
+ }
+
+ };
+
+ OrderBy(const Stability stability,
+ const OrderSpec::Vector &orderSpecs,
+ const Expression::Ptr &operand,
+ ReturnOrderBy *const returnOrderBy);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline Item::Iterator::Ptr mapToSequence(const Item &i,
+ const DynamicContext::Ptr &context) const;
+ virtual Properties properties() const;
+
+ private:
+ /**
+ * Needed when calling makeSequenceMappingIterator().
+ */
+ typedef QExplicitlySharedDataPointer<const OrderBy> ConstPtr;
+
+ const Stability m_stability;
+ OrderSpec::Vector m_orderSpecs;
+ ReturnOrderBy *const m_returnOrderBy;
+ };
+
+ /* TODO Q_DECLARE_TYPEINFO(OrderBy::OrderSpec, Q_MOVABLE_TYPE); Breaks,
+ * probably because it's nested. */
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qorexpression.cpp b/src/xmlpatterns/expr/qorexpression.cpp
new file mode 100644
index 0000000..c2bbe3c
--- /dev/null
+++ b/src/xmlpatterns/expr/qorexpression.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qorexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+OrExpression::OrExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : AndExpression(operand1, operand2)
+{
+}
+
+bool OrExpression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context) || m_operand2->evaluateEBV(context);
+}
+
+Expression::Ptr OrExpression::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr newMe(PairContainer::compress(context));
+
+ if(newMe != this)
+ return newMe;
+
+ /* Both operands mustn't be evaluated in order to be able to compress. */
+ if(m_operand1->isEvaluated() && m_operand1->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else if(m_operand2->isEvaluated() && m_operand2->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else
+ return Expression::Ptr(this);
+}
+
+ExpressionVisitorResult::Ptr OrExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qorexpression_p.h b/src/xmlpatterns/expr/qorexpression_p.h
new file mode 100644
index 0000000..c86f654
--- /dev/null
+++ b/src/xmlpatterns/expr/qorexpression_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_OrExpression_H
+#define Patternist_OrExpression_H
+
+#include "qandexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's logical expression @c or.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-logical-expressions">XML Path Language
+ * (XPath) 2.0, 3.6 Logical Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class OrExpression : public AndExpression
+ {
+ public:
+ OrExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qpaircontainer.cpp b/src/xmlpatterns/expr/qpaircontainer.cpp
new file mode 100644
index 0000000..7ca7b53
--- /dev/null
+++ b/src/xmlpatterns/expr/qpaircontainer.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+PairContainer::PairContainer(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : m_operand1(operand1),
+ m_operand2(operand2)
+{
+ Q_ASSERT(m_operand1);
+ Q_ASSERT(m_operand2);
+}
+
+Expression::List PairContainer::operands() const
+{
+ Expression::List list;
+ list.append(m_operand1);
+ list.append(m_operand2);
+ return list;
+}
+
+void PairContainer::setOperands(const Expression::List &ops)
+{
+ Q_ASSERT(ops.count() == 2);
+ m_operand1 = ops.first();
+ m_operand2 = ops.last();
+ Q_ASSERT(m_operand1);
+ Q_ASSERT(m_operand2);
+}
+
+bool PairContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ Q_ASSERT(m_operand1);
+ Q_ASSERT(m_operand2);
+ rewrite(m_operand1, m_operand1->compress(context), context);
+ rewrite(m_operand2, m_operand2->compress(context), context);
+
+ return m_operand1->isEvaluated() && m_operand2->isEvaluated();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qpaircontainer_p.h b/src/xmlpatterns/expr/qpaircontainer_p.h
new file mode 100644
index 0000000..7acf7df
--- /dev/null
+++ b/src/xmlpatterns/expr/qpaircontainer_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_PairContainer_H
+#define Patternist_PairContainer_H
+
+#include "qexpression_p.h"
+#include "qatomictype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has exactly two operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class PairContainer : public Expression
+ {
+ public:
+ virtual Expression::List operands() const;
+ virtual void setOperands(const Expression::List &operands);
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ protected:
+ PairContainer(const Expression::Ptr &operand1, const Expression::Ptr &operand2);
+
+ Expression::Ptr m_operand1;
+ Expression::Ptr m_operand2;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qparentnodeaxis.cpp b/src/xmlpatterns/expr/qparentnodeaxis.cpp
new file mode 100644
index 0000000..b715782
--- /dev/null
+++ b/src/xmlpatterns/expr/qparentnodeaxis.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "qparentnodeaxis_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ParentNodeAxis::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->contextItem().asNode().iterate(QXmlNodeModelIndex::AxisParent)->next();
+}
+
+Expression::Properties ParentNodeAxis::properties() const
+{
+ return DisableElimination | RequiresContextItem;
+}
+
+ExpressionVisitorResult::Ptr ParentNodeAxis::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+ItemType::Ptr ParentNodeAxis::expectedContextItemType() const
+{
+ return BuiltinTypes::node;
+}
+
+SequenceType::Ptr ParentNodeAxis::staticType() const
+{
+ // Parentless node exists.
+ return CommonSequenceTypes::ZeroOrOneNode;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qparentnodeaxis_p.h b/src/xmlpatterns/expr/qparentnodeaxis_p.h
new file mode 100644
index 0000000..ee5529f
--- /dev/null
+++ b/src/xmlpatterns/expr/qparentnodeaxis_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ParentNodeAxis_H
+#define Patternist_ParentNodeAxis_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Corresponds to the expression <tt>parent::node()</tt>.
+ *
+ * This AST node is now useless, due to refactorings. Prevously we had
+ * Item QAbstractXmlNodeModel::parent(), which didn't have the overhead of
+ * allocating an iterator for a single node. However, in order to stream
+ * line the API it is now gone and hence the node performs exactly the same
+ * as AxisStep.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ParentNodeAxis : public EmptyContainer
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always DisableElimination
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneNode;
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns always BuiltinTypes::node;
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qpath.cpp b/src/xmlpatterns/expr/qpath.cpp
new file mode 100644
index 0000000..73cf0d9
--- /dev/null
+++ b/src/xmlpatterns/expr/qpath.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qnodesort_p.h"
+#include "qpatternistlocale_p.h"
+#include "qsequencemappingiterator_p.h"
+#include "qtypechecker_p.h"
+
+#include "qpath_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Path::Path(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Kind kind) : PairContainer(operand1, operand2)
+ , m_hasCreatedSorter(kind != RegularPath)
+ , m_isLast(false)
+ , m_checkXPTY0018(kind == RegularPath)
+ , m_kind(kind)
+{
+}
+
+Item::Iterator::Ptr Path::mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ /* item is the focus here. That is in <e/>/1, item is <e/>. However,
+ * we don't use it, since the context item is accessed through
+ * DynamicContext::focusIterator() and friends. */
+ Q_ASSERT(item);
+ Q_UNUSED(item); /* Needed when compiling in release mode. */
+ return m_operand2->evaluateSequence(context);
+}
+
+Item::Iterator::Ptr Path::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ /* Note, we use the old context for m_operand1. */
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(source);
+
+ const Item::Iterator::Ptr result(makeSequenceMappingIterator<Item>(ConstPtr(this), source, focus));
+
+ if(m_checkXPTY0018)
+ {
+ /* This is an expensive code path, but it should happen very rarely. */
+
+ enum FoundItem
+ {
+ FoundNone,
+ FoundNode,
+ FoundAtomicValue
+ } hasFound = FoundNone;
+
+ Item::List whenChecked;
+
+ Item next(result->next());
+
+ while(next)
+ {
+ const FoundItem found = next.isAtomicValue() ? FoundAtomicValue : FoundNode;
+
+ if(hasFound != FoundNone && hasFound != found)
+ {
+ /* It's an atomic value and we've already found a node. Mixed content. */
+ context->error(QtXmlPatterns::tr("The last step in a path must contain either nodes "
+ "or atomic values. It cannot be a mixture between the two."),
+ ReportContext::XPTY0018, this);
+ }
+ else
+ hasFound = found;
+
+ whenChecked.append(next);
+ next = result->next();
+ }
+
+ return makeListIterator(whenChecked);
+ }
+ else
+ return result;
+}
+
+Item Path::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ /* This function is called if both operands' cardinality is exactly-one. Therefore
+ * we manually go forward in the focus by calling next().
+ *
+ * We don't check for XPTY0018, only in evaluateSequence(), since if we're guaranteed
+ * to evaluate to one item, we can only evaluate to one node or one atomic value.
+ */
+
+ /* Note, we use the old context for m_operand1. */
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(source);
+
+ /* This test is needed because if the focus is empty, we don't want to(nor can't) evaluate
+ * the next step. */
+ // TODO Why are we at all invoked then?
+ if(source->next())
+ return m_operand2->evaluateSingleton(focus);
+ else
+ return Item();
+}
+
+void Path::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ /* Note, we use the old context for m_operand1. */
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(source);
+
+ while(source->next())
+ m_operand2->evaluateToSequenceReceiver(focus);
+}
+
+Expression::Ptr Path::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ /* "./expr" is by now equal to "expr" since we've done
+ * focus/type checks, and a node sorter has been inserted. */
+ if(m_operand1->is(IDContextItem))
+ return m_operand2;
+
+ /* We do this as late as we can, such that we pick up the most recent type
+ * from the operand. */
+ if(m_isLast && m_kind != XSLTForEach && m_operand2->staticType()->itemType() == BuiltinTypes::item)
+ m_checkXPTY0018 = true;
+
+ return me;
+}
+
+Expression::Ptr Path::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_operand2->announceFocusType(newFocusType());
+
+ /* Here we apply the function conversion first, and with the error code
+ * that we want -- XPTY0019 instead of XPTY0004. Unfortunately
+ * PairContainer::typeCheck() will do the type check again, which is
+ * redundant in the case of when we're not XSLTForEach.
+ *
+ * If we're XSLTForEach, it means we're a synthetic "map" expression for
+ * implementing various XSL-T expressions, and hence don't have the
+ * constraint of XPTY0019.
+ *
+ * It's important that typeCheck() is run for the operands(of course), and the call to
+ * PairContainer::typeCheck() ensures that below, in the case that we're XSL-T code.
+ *
+ * The type we expect, CommonSequenceTypes::ZeroOrMoreNodes() needs to be in sync with
+ * what we return in expectedOperandTypes(). */
+ if(m_kind != XSLTForEach)
+ {
+ m_operand1 = TypeChecker::applyFunctionConversion(m_operand1,
+ CommonSequenceTypes::ZeroOrMoreNodes,
+ context,
+ m_kind == ForApplyTemplate ? ReportContext::XTTE0520
+ : ReportContext::XPTY0019);
+ }
+
+ /* If our step ends with atomic values, we cannot sort.
+ *
+ * We must smack the NodeSortExpression ontop before calling typeCheck(), since the latter
+ * may insert an Atomizer, as possibly mandated by reqType. By doing it after, the Atomizer
+ * will be a parent to NodeSortExpression, as opposed to a child.
+ */
+ if(!m_hasCreatedSorter)
+ {
+ m_hasCreatedSorter = true;
+
+ return NodeSortExpression::wrapAround(Expression::Ptr(this), context)->typeCheck(context, reqType);
+ }
+ else
+ return PairContainer::typeCheck(context, reqType);
+}
+
+SequenceType::List Path::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ /* This value needs to be in sync with what we pass to
+ * applyFunctionConversion() in typeCheck() above.
+ *
+ * We don't have the XPTY0019 restriction when we're synthetic XSL-T code.
+ */
+ if(m_kind == XSLTForEach)
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ else
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr Path::staticType() const
+{
+ const SequenceType::Ptr opType(m_operand2->staticType());
+
+ /* For each parent step, we evaluate the child step. So multiply the two
+ * cardinalities. */
+ return makeGenericSequenceType(opType->itemType(),
+ m_operand1->staticType()->cardinality() * opType->cardinality());
+}
+
+ExpressionVisitorResult::Ptr Path::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties Path::properties() const
+{
+ return CreatesFocusForLast | ((m_operand1->properties() | m_operand2->properties()) & (RequiresCurrentItem | DisableElimination));
+}
+
+ItemType::Ptr Path::newFocusType() const
+{
+ return m_operand1->staticType()->itemType();
+}
+
+Expression::ID Path::id() const
+{
+ return IDPath;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qpath_p.h b/src/xmlpatterns/expr/qpath_p.h
new file mode 100644
index 0000000..e4dc365
--- /dev/null
+++ b/src/xmlpatterns/expr/qpath_p.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Path_H
+#define Patternist_Path_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the path expression, containing two steps, such as in <tt>html/body</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-path-expressions">XQuery 1.0: An
+ * XML Query Language, 3.2 Path Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Path : public PairContainer
+ {
+ public:
+ enum Kind
+ {
+ /**
+ * This Path is a plain old path expression as found in XPath.
+ * Sorting is performed, and atomics are disallowed as left
+ * operand.
+ */
+ RegularPath = 1,
+
+ /**
+ * This Path emulates an @c xsl:for-each instruction. This means no
+ * sorting of result, and atomics are allowed as left operand.
+ */
+ XSLTForEach,
+
+ /**
+ * This Path performs the iteration in an @c xsl:apply-templates
+ * instruction. This means sorting, and atomics are disallowed
+ * as left operand.
+ */
+ ForApplyTemplate
+ };
+
+ Path(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Kind kind = RegularPath);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns the static type of the last step where the cardinality is multiplied with
+ * the cardinality of the first step's cardinality.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns the item type of the last step's static type.
+ */
+ virtual ItemType::Ptr newFocusType() const;
+
+ virtual ID id() const;
+
+ inline void setLast();
+
+ inline Kind kind() const
+ {
+ return m_kind;
+ }
+
+ private:
+ typedef QExplicitlySharedDataPointer<const Path> ConstPtr;
+
+ /**
+ * One might think this block exists for preventing multiple
+ * NodeSortExpressions to be created. However, that is not an issue,
+ * since NodeSortExpression optimizes this away anyway.
+ *
+ * The real reason is to avoid infinite recursion. When our typeCheck()
+ * forwards on the type check to the just created
+ * NodeSortExpression, it in turn calls typeCheck() on its child, which
+ * is this Path. Rince and repeat.
+ *
+ * We only create node sorts when we're a regular path expression, and
+ * not when standing in as a generic map expression. */
+ bool m_hasCreatedSorter;
+
+ /**
+ * Whether this path is the step. For instance, in <tt>a/b/c</tt>, the
+ * last path has @c c as the right operand.
+ */
+ bool m_isLast;
+
+ bool m_checkXPTY0018;
+ const Kind m_kind;
+ };
+
+ void Path::setLast()
+ {
+ m_isLast = true;
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qpositionalvariablereference.cpp b/src/xmlpatterns/expr/qpositionalvariablereference.cpp
new file mode 100644
index 0000000..0b4f69b
--- /dev/null
+++ b/src/xmlpatterns/expr/qpositionalvariablereference.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qinteger_p.h"
+
+#include "qpositionalvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+PositionalVariableReference::PositionalVariableReference(const VariableSlotID s) : VariableReference(s)
+{
+}
+
+Item PositionalVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ Q_ASSERT(context->positionIterator(slot()));
+ return Integer::fromValue(context->positionIterator(slot())->position());
+}
+
+bool PositionalVariableReference::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return true;
+}
+
+SequenceType::Ptr PositionalVariableReference::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneInteger;
+}
+
+Expression::Properties PositionalVariableReference::properties() const
+{
+ return DependsOnLocalVariable;
+}
+
+ExpressionVisitorResult::Ptr
+
+PositionalVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qpositionalvariablereference_p.h b/src/xmlpatterns/expr/qpositionalvariablereference_p.h
new file mode 100644
index 0000000..9fe3cbd
--- /dev/null
+++ b/src/xmlpatterns/expr/qpositionalvariablereference_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_PositionVariableReference_H
+#define Patternist_PositionVariableReference_H
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to an @c at variable, declared with the
+ * <tt>for</tt>-part in XQuery's FLWOR expression.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class PositionalVariableReference : public VariableReference
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<PositionalVariableReference> Ptr;
+ PositionalVariableReference(const VariableSlotID slot);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Returns always @c true, since a positional variable is always one or more, and the
+ * Effective %Boolean Value for that range is always @c true.
+ *
+ * @returns always @c true
+ */
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneInteger
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp b/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp
new file mode 100644
index 0000000..d933ee0
--- /dev/null
+++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qnodebuilder_p.h"
+#include "qqnamevalue_p.h"
+
+#include "qprocessinginstructionconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ProcessingInstructionConstructor::
+ProcessingInstructionConstructor(const Expression::Ptr &op1,
+ const Expression::Ptr &op2) : PairContainer(op1, op2)
+{
+}
+
+QString ProcessingInstructionConstructor::leftTrimmed(const QString &input)
+{
+ const int len = input.length();
+
+ for(int i = 0; i < len; ++i)
+ {
+ if(!input.at(i).isSpace())
+ return input.mid(i);
+ }
+
+ return QString(); /* input consists only of whitespace. All was trimmed. */
+}
+
+QString ProcessingInstructionConstructor::data(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand1->evaluateSingleton(context));
+ const Item dataArg(m_operand2->evaluateSingleton(context));
+
+ if(dataArg)
+ {
+ /* Perform trimming before validation, to increase speed. */
+ const QString value(leftTrimmed(dataArg.stringValue()));
+
+ if(value.contains(QLatin1String("?>")))
+ {
+ context->error(QtXmlPatterns::tr("The data of a processing instruction cannot contain the string %1").arg(formatData("?>")),
+ ReportContext::XQDY0026, this);
+ return QString();
+ }
+ else
+ return value;
+ }
+ else
+ return QString();
+}
+
+QXmlName ProcessingInstructionConstructor::evaluateTardata(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand1->evaluateSingleton(context));
+ return context->namePool()->allocateQName(QString(), name.stringValue());
+}
+
+Item ProcessingInstructionConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+
+ nodeBuilder->processingInstruction(evaluateTardata(context), data(context));
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void ProcessingInstructionConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ receiver->processingInstruction(evaluateTardata(context), data(context));
+}
+
+SequenceType::Ptr ProcessingInstructionConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneProcessingInstruction;
+}
+
+SequenceType::List ProcessingInstructionConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties ProcessingInstructionConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+ProcessingInstructionConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h b/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h
new file mode 100644
index 0000000..950ebc8
--- /dev/null
+++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ProcessingInstructionConstructor_H
+#define Patternist_ProcessingInstructionConstructor_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs an element node. This covers both computed and directly constructed
+ * element nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ProcessingInstructionConstructor : public PairContainer
+ {
+ public:
+ ProcessingInstructionConstructor(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Both arguments must of type @c xs:string. It is assumes that the first argument's
+ * lexical space is @c xs:NCName.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+ private:
+ inline QXmlName evaluateTardata(const DynamicContext::Ptr &context) const;
+ /**
+ * Performs left-trimming only.
+ *
+ * @see QString::trimmed()
+ */
+ static inline QString leftTrimmed(const QString &input);
+
+ QString data(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qqnameconstructor.cpp b/src/xmlpatterns/expr/qqnameconstructor.cpp
new file mode 100644
index 0000000..7925e2b
--- /dev/null
+++ b/src/xmlpatterns/expr/qqnameconstructor.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+
+#include "qqnameconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QNameConstructor::QNameConstructor(const Expression::Ptr &source,
+ const NamespaceResolver::Ptr &nsResolver) : SingleContainer(source),
+ m_nsResolver(nsResolver)
+{
+ Q_ASSERT(m_nsResolver);
+}
+
+Item QNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ const QString lexQName(m_operand->evaluateSingleton(context).stringValue());
+
+ const QXmlName expQName(expandQName<DynamicContext::Ptr,
+ ReportContext::XQDY0074,
+ ReportContext::XQDY0074>(lexQName,
+ context,
+ m_nsResolver,
+ this));
+ return toItem(QNameValue::fromValue(context->namePool(), expQName));
+}
+
+QXmlName::NamespaceCode QNameConstructor::namespaceForPrefix(const QXmlName::PrefixCode prefix,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+{
+ Q_ASSERT(context);
+ const QXmlName::NamespaceCode ns(context->namespaceBindings()->lookupNamespaceURI(prefix));
+
+ if(ns == NamespaceResolver::NoBinding)
+ {
+ context->error(QtXmlPatterns::tr("No namespace binding exists for the prefix %1")
+ .arg(formatKeyword(context->namePool()->stringForPrefix(prefix))),
+ ReportContext::XPST0081,
+ r);
+ return NamespaceResolver::NoBinding;
+ }
+ else
+ return ns;
+}
+
+SequenceType::Ptr QNameConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneQName;
+}
+
+SequenceType::List QNameConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr QNameConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *QNameConstructor::actualReflection() const
+{
+ return m_operand.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qqnameconstructor_p.h b/src/xmlpatterns/expr/qqnameconstructor_p.h
new file mode 100644
index 0000000..4011870
--- /dev/null
+++ b/src/xmlpatterns/expr/qqnameconstructor_p.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_QNameConstructor_H
+#define Patternist_QNameConstructor_H
+
+#include "qsinglecontainer_p.h"
+#include "qbuiltintypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qxpathhelper_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Creates an @c xs:QName value from a lexical QName using
+ * statically known namespace bindings.
+ *
+ * @see QQNameValue
+ * @see QXmlUtils
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class QNameConstructor : public SingleContainer
+ {
+ public:
+
+ QNameConstructor(const Expression::Ptr &source,
+ const NamespaceResolver::Ptr &nsResolver);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Expands @p lexicalQName, which is a lexical representation of a QName such as "x:body", into
+ * a QName using @p nsResolver to supply the namespace bindings.
+ *
+ * If @p lexicalQName is lexically invalid @p InvalidQName is raised via @p context, or if
+ * no namespace binding does not exists for a prefix(if any) in @p lexicalQName, @p NoBinding
+ * is raised via @p context.
+ *
+ * If @p asForAttribute is @c true, the name is considered to be for an
+ * attribute in some way, and @p lexicalQName will not pick up the
+ * default namespace if it doesn't have a prefix.
+ *
+ * @p nsResolver is parameterized meaning the function can be instantiated with either
+ * DynamicContext or StaticContext.
+ *
+ * @see QQNameValue
+ * @see QXmlUtils
+ */
+ template<typename TReportContext,
+ const ReportContext::ErrorCode InvalidQName,
+ const ReportContext::ErrorCode NoBinding>
+ static
+ QXmlName expandQName(const QString &lexicalQName,
+ const TReportContext &context,
+ const NamespaceResolver::Ptr &nsResolver,
+ const SourceLocationReflection *const r,
+ const bool asForAttribute = false);
+
+ /**
+ * Resolves the namespace prefix @p prefix to its namespace if it exists, or
+ * raised ReportContext::XPST0081 otherwise.
+ *
+ * @returns the namespace URI corresponding to @p prefix
+ */
+ static QXmlName::NamespaceCode namespaceForPrefix(const QXmlName::PrefixCode prefix,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r);
+
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ const NamespaceResolver::Ptr m_nsResolver;
+ };
+
+ template<typename TReportContext,
+ const ReportContext::ErrorCode InvalidQName,
+ const ReportContext::ErrorCode NoBinding>
+ QXmlName QNameConstructor::expandQName(const QString &lexicalQName,
+ const TReportContext &context,
+ const NamespaceResolver::Ptr &nsResolver,
+ const SourceLocationReflection *const r,
+ const bool asForAttribute)
+ {
+ Q_ASSERT(nsResolver);
+ Q_ASSERT(context);
+
+ if(XPathHelper::isQName(lexicalQName))
+ {
+ QString prefix;
+ QString local;
+ XPathHelper::splitQName(lexicalQName, prefix, local);
+ const QXmlName::NamespaceCode nsCode = asForAttribute && prefix.isEmpty() ? QXmlName::NamespaceCode(StandardNamespaces::empty)
+ : (nsResolver->lookupNamespaceURI(context->namePool()->allocatePrefix(prefix)));
+
+ if(nsCode == NamespaceResolver::NoBinding)
+ {
+ context->error(QtXmlPatterns::tr("No namespace binding exists for "
+ "the prefix %1 in %2").arg(formatKeyword(prefix),
+ formatKeyword(lexicalQName)),
+ NoBinding,
+ r);
+ return QXmlName(); /* Silence compiler warning. */
+ }
+ else
+ return context->namePool()->allocateQName(context->namePool()->stringForNamespace(nsCode), local, prefix);
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("%1 is an invalid %2")
+ .arg(formatData(lexicalQName))
+ .arg(formatType(context->namePool(), BuiltinTypes::xsQName)),
+ InvalidQName,
+ r);
+ return QXmlName(); /* Silence compiler warning. */
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qquantifiedexpression.cpp b/src/xmlpatterns/expr/qquantifiedexpression.cpp
new file mode 100644
index 0000000..a6c4d03
--- /dev/null
+++ b/src/xmlpatterns/expr/qquantifiedexpression.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+
+#include "qquantifiedexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QuantifiedExpression::QuantifiedExpression(const VariableSlotID varSlot,
+ const Operator quantifier,
+ const Expression::Ptr &inClause,
+ const Expression::Ptr &testExpression)
+ : PairContainer(inClause, testExpression),
+ m_varSlot(varSlot),
+ m_quantifier(quantifier)
+{
+ Q_ASSERT(quantifier == Some || quantifier == Every);
+}
+
+Item QuantifiedExpression::mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ context->setRangeVariable(m_varSlot, item);
+ return item;
+}
+
+bool QuantifiedExpression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(makeItemMappingIterator<Item>(ConstPtr(this),
+ m_operand1->evaluateSequence(context),
+ context));
+
+ Item item(it->next());
+
+ if(m_quantifier == Some)
+ {
+ while(item)
+ {
+ if(m_operand2->evaluateEBV(context))
+ return true;
+ else
+ item = it->next();
+ };
+
+ return false;
+ }
+ else
+ {
+ Q_ASSERT(m_quantifier == Every);
+
+ while(item)
+ {
+ if(m_operand2->evaluateEBV(context))
+ item = it->next();
+ else
+ return false;
+ }
+
+ return true;
+ }
+}
+
+QString QuantifiedExpression::displayName(const Operator quantifier)
+{
+ if(quantifier == Some)
+ return QLatin1String("some");
+ else
+ {
+ Q_ASSERT(quantifier == Every);
+ return QLatin1String("every");
+ }
+}
+
+SequenceType::Ptr QuantifiedExpression::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+SequenceType::List QuantifiedExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::EBV);
+ return result;
+}
+
+QuantifiedExpression::Operator QuantifiedExpression::operatorID() const
+{
+ return m_quantifier;
+}
+
+ExpressionVisitorResult::Ptr QuantifiedExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qquantifiedexpression_p.h b/src/xmlpatterns/expr/qquantifiedexpression_p.h
new file mode 100644
index 0000000..0c65782
--- /dev/null
+++ b/src/xmlpatterns/expr/qquantifiedexpression_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_QuantifiedExpression_H
+#define Patternist_QuantifiedExpression_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's quantification expressions @c some and @c every.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-quantified-expressions">XML Path Language
+ * (XPath) 2.0, 3.9 Quantified Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT QuantifiedExpression : public PairContainer
+ {
+ public:
+ enum Operator
+ {
+ Some = 1,
+ Every
+ };
+
+ QuantifiedExpression(const VariableSlotID varSlot,
+ const Operator quantifier,
+ const Expression::Ptr &inClause,
+ const Expression::Ptr &testExpression);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ Operator operatorID() const;
+
+ /**
+ * Determines the string representation for a quantification operator.
+ *
+ * @return "some" if @p quantifier is Some, or "every" if @p quantifier
+ * is Every
+ */
+ static QString displayName(const Operator quantifier);
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline Item mapToItem(const Item &item, const DynamicContext::Ptr &context) const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const QuantifiedExpression> ConstPtr;
+ const VariableSlotID m_varSlot;
+ const Operator m_quantifier;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qrangeexpression.cpp b/src/xmlpatterns/expr/qrangeexpression.cpp
new file mode 100644
index 0000000..b4d7e91
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangeexpression.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qinteger_p.h"
+#include "qliteral_p.h"
+#include "qrangeiterator_p.h"
+
+#include "qrangeexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+RangeExpression::RangeExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : PairContainer(operand1, operand2)
+{
+}
+
+Item::Iterator::Ptr RangeExpression::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item s(m_operand1->evaluateSingleton(context));
+
+ if(!s)
+ return CommonValues::emptyIterator;
+
+ const Item e(m_operand2->evaluateSingleton(context));
+ if(!e)
+ return CommonValues::emptyIterator;
+
+ const xsInteger start = s.as<Numeric>()->toInteger();
+ const xsInteger end = e.as<Numeric>()->toInteger();
+
+ if(start > end)
+ return CommonValues::emptyIterator;
+ else if(start == end)
+ return makeSingletonIterator(s);
+ else
+ return Item::Iterator::Ptr(new RangeIterator(start, RangeIterator::Forward, end));
+}
+
+Item RangeExpression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateSingleton(context);
+}
+
+SequenceType::List RangeExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneInteger);
+ result.append(CommonSequenceTypes::ZeroOrOneInteger);
+ return result;
+}
+
+SequenceType::Ptr RangeExpression::staticType() const
+{
+ /* This logic makes the Cardinality more specific. */
+ Cardinality::Count from;
+ bool hasFrom;
+
+ if(m_operand1->is(IDIntegerValue))
+ {
+ from = m_operand1->as<Literal>()->item().as<Integer>()->toInteger();
+ hasFrom = true;
+ }
+ else
+ {
+ hasFrom = false;
+ from = 0;
+ }
+
+ /* We can't check whether to is -1 since maybe the user wrote -1. Hence
+ * hasTo is required. */
+ bool hasTo;
+ Cardinality::Count to;
+
+ if(m_operand2->is(IDIntegerValue))
+ {
+ const xsInteger asInt = m_operand2->as<Literal>()->item().as<Integer>()->toInteger();
+ to = asInt;
+
+ if(to == asInt)
+ hasTo = true;
+ else
+ {
+ /* Cardinality::Count is not the same as type xsInteger. We had overflow. */
+ to = -1;
+ hasTo = false;
+ }
+ }
+ else
+ {
+ to = -1;
+ hasTo = false;
+ }
+
+ if(hasTo && hasFrom)
+ {
+ if(from > to)
+ {
+ /* The query is incorrectly written, we'll evaluate to the empty sequence.
+ * Just return what's correct. */
+ return CommonSequenceTypes::ZeroOrMoreIntegers;
+ }
+ else
+ {
+ Cardinality::Count count = (to - from) + 1; /* + 1, since it's inclusive. */
+ return makeGenericSequenceType(BuiltinTypes::xsInteger, Cardinality::fromExact(count));
+ }
+ }
+ else
+ {
+ /* We can't do fromExact(from, -1) since the latter can evaluate to a value that actually is
+ * lower than from, although that unfortunately is very unlikely. */
+ return CommonSequenceTypes::ZeroOrMoreIntegers;
+ }
+}
+
+Expression::Properties RangeExpression::properties() const
+{
+ return Expression::DisableElimination;
+}
+
+ExpressionVisitorResult::Ptr RangeExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qrangeexpression_p.h b/src/xmlpatterns/expr/qrangeexpression_p.h
new file mode 100644
index 0000000..94756d7
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangeexpression_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_RangeExpression_H
+#define Patternist_RangeExpression_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's @c to expression.
+ *
+ * Despite its name, RangeExpression is not related to RangeVariableDeclaration.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#construct_seq">XML Path Language
+ * (XPath) 2.0, 3.3.1 Constructing Sequences</a>
+ * @see RangeIterator
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class RangeExpression : public PairContainer
+ {
+ public:
+ RangeExpression(const Expression::Ptr &operand1, const Expression::Ptr &operand2);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ /**
+ * It's likely that this function gets called if staticType() inferred
+ * the cardinality to an exact number. In that case, we know that the
+ * first arguments is the same as the second argument.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns always CommonSequenceTypes::ZeroOrMoreIntegers
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Disables compression for optimization reasons. For example, the
+ * expression "1 to 1000" would consume thousand allocated instances
+ * of Integer, and RangeIterator is well suited for dynamic evaluation.
+ *
+ * @returns Expression::DisableElimination
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qrangevariablereference.cpp b/src/xmlpatterns/expr/qrangevariablereference.cpp
new file mode 100644
index 0000000..e4d6c7e
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangevariablereference.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qrangevariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+RangeVariableReference::RangeVariableReference(const Expression::Ptr &source,
+ const VariableSlotID slotP) : VariableReference(slotP),
+ m_sourceExpression(source)
+{
+ Q_ASSERT(source);
+}
+
+bool RangeVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT_X(context->rangeVariable(slot()), Q_FUNC_INFO, "The range variable must be set.");
+ return Boolean::evaluateEBV(context->rangeVariable(slot()), context);
+}
+
+Item RangeVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT_X(context->rangeVariable(slot()), Q_FUNC_INFO, "The range variable must be set.");
+ return context->rangeVariable(slot());
+}
+
+SequenceType::Ptr RangeVariableReference::staticType() const
+{
+ return makeGenericSequenceType(m_sourceExpression->staticType()->itemType(),
+ Cardinality::exactlyOne());
+}
+
+Expression::ID RangeVariableReference::id() const
+{
+ return IDRangeVariableReference;
+}
+
+ExpressionVisitorResult::Ptr
+RangeVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties RangeVariableReference::properties() const
+{
+ return DependsOnLocalVariable;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qrangevariablereference_p.h b/src/xmlpatterns/expr/qrangevariablereference_p.h
new file mode 100644
index 0000000..1246937
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangevariablereference_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_RangeVariableReference_H
+#define Patternist_RangeVariableReference_H
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to a variable declared with @c for or a quantification
+ * expression, but not for instance a @c let binding.
+ *
+ * A range variable always represents a single item, while an other
+ * expression provides the binding and iteration. A @c for expression is
+ * a good example.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class RangeVariableReference : public VariableReference
+ {
+ public:
+ RangeVariableReference(const Expression::Ptr &sourceExpression,
+ const VariableSlotID slot);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns IDRangeVariableReference
+ */
+ virtual ID id() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ private:
+ const Expression::Ptr m_sourceExpression;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qreturnorderby.cpp b/src/xmlpatterns/expr/qreturnorderby.cpp
new file mode 100644
index 0000000..c530971
--- /dev/null
+++ b/src/xmlpatterns/expr/qreturnorderby.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qexpressionsequence_p.h"
+#include "qsorttuple_p.h"
+
+#include "qreturnorderby_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ReturnOrderBy::ReturnOrderBy(const OrderBy::Stability aStability,
+ const OrderBy::OrderSpec::Vector &oSpecs,
+ const Expression::List &ops) : UnlimitedContainer(ops)
+ , m_stability(aStability)
+ , m_orderSpecs(oSpecs)
+ , m_flyAway(true)
+{
+ Q_ASSERT_X(m_operands.size() >= 2, Q_FUNC_INFO,
+ "ReturnOrderBy must have the return expression, and at least one sort key.");
+ Q_ASSERT(m_orderSpecs.size() == ops.size() - 1);
+}
+
+Item ReturnOrderBy::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_operands.size() > 1);
+ const Item::Iterator::Ptr value(makeListIterator(m_operands.first()->evaluateSequence(context)->toList()));
+ Item::Vector sortKeys;
+
+ /* We're skipping the first operand. */
+ const int len = m_operands.size() - 1;
+ sortKeys.resize(len);
+
+ for(int i = 1; i <= len; ++i)
+ sortKeys[i - 1] = m_operands.at(i)->evaluateSingleton(context);
+
+ return Item(new SortTuple(value, sortKeys));
+}
+
+bool ReturnOrderBy::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ // TODO This is temporary code.
+ return m_operands.first()->evaluateEBV(context);
+}
+
+Expression::Ptr ReturnOrderBy::compress(const StaticContext::Ptr &context)
+{
+ /* We first did this in typeCheck(), but that broke due to that type checks were
+ * missed, which other pieces relied on. */
+ if(m_flyAway)
+ {
+ /* We only want the return expression, not the sort keys. */
+ return m_operands.first()->compress(context);
+ }
+ else
+ {
+ /* We don't need the members, so don't keep a reference to them. */
+ m_orderSpecs.clear();
+
+ return UnlimitedContainer::compress(context);
+ }
+}
+
+Expression::Properties ReturnOrderBy::properties() const
+{
+ /* For some unknown reason this is necessary for XQTS test case orderBy18. */
+ return DisableElimination;
+}
+
+ExpressionVisitorResult::Ptr ReturnOrderBy::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr ReturnOrderBy::staticType() const
+{
+ return m_operands.first()->staticType();
+}
+
+SequenceType::List ReturnOrderBy::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ return result;
+}
+
+Expression::ID ReturnOrderBy::id() const
+{
+ return IDReturnOrderBy;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qreturnorderby_p.h b/src/xmlpatterns/expr/qreturnorderby_p.h
new file mode 100644
index 0000000..6a51717
--- /dev/null
+++ b/src/xmlpatterns/expr/qreturnorderby_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ReturnOrderBy_H
+#define Patternist_ReturnOrderBy_H
+
+#include "qorderby_p.h"
+#include "qunlimitedcontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Together with OrderBy, it implements XQuery 1.0's <tt>order by</tt> expression.
+ *
+ * ReturnOrderBy evaluates the sort keys and values, and hands it over to
+ * OrderBy, which is an AST ancestor, using SortTuples.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ReturnOrderBy : public UnlimitedContainer
+ {
+ public:
+ /**
+ * In @p operands the first item is the return expression, and the
+ * rest, which is at least one, are the sort keys.
+ */
+ ReturnOrderBy(const OrderBy::Stability stability,
+ const OrderBy::OrderSpec::Vector &oSpecs,
+ const Expression::List &operands);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ inline OrderBy::OrderSpec::Vector orderSpecs() const
+ {
+ return m_orderSpecs;
+ }
+
+ inline OrderBy::Stability stability() const
+ {
+ return m_stability;
+ }
+
+ /**
+ * In the case of that we don't have a for-expression beloning us, but
+ * only a let clause, this ReturnOrderBy breaks if it stays in the AST.
+ * So, by default we assume that we should write ourselves away, unless
+ * this function is called. The associated ForClause will call it
+ * during typeCheck(), if it exists.
+ */
+ inline void setStay(const bool a)
+ {
+ m_flyAway = !a;
+ }
+
+ virtual Properties properties() const;
+ private:
+ /**
+ * This variable is unfortunately only used at compile time. However,
+ * it's tricky to get rid of it due to how QueryTransformParser would
+ * have to be adapted.
+ */
+ const OrderBy::Stability m_stability;
+
+ OrderBy::OrderSpec::Vector m_orderSpecs;
+
+ /**
+ * @see stay()
+ */
+ bool m_flyAway;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qsimplecontentconstructor.cpp b/src/xmlpatterns/expr/qsimplecontentconstructor.cpp
new file mode 100644
index 0000000..e98d988
--- /dev/null
+++ b/src/xmlpatterns/expr/qsimplecontentconstructor.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qatomicstring_p.h"
+
+#include "qsimplecontentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SimpleContentConstructor::SimpleContentConstructor(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+Item SimpleContentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ Item next(it->next());
+ QString result;
+
+ if(next)
+ {
+ result = next.stringValue();
+ next = it->next();
+ }
+ else
+ return Item();
+
+ while(next)
+ {
+ result += QLatin1Char(' ');
+ result += next.stringValue();
+ next = it->next();
+ }
+
+ return AtomicString::fromValue(result);
+}
+
+Expression::Ptr SimpleContentConstructor::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me.data() == this)
+ {
+ /* Optimization: if we will evaluate to a single string, we're not
+ * necessary. */
+ if(CommonSequenceTypes::ExactlyOneString->matches(m_operand->staticType()))
+ return m_operand;
+ }
+
+ return me;
+}
+
+SequenceType::List SimpleContentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ return result;
+}
+
+SequenceType::Ptr SimpleContentConstructor::staticType() const
+{
+ if(m_operand->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneString;
+ else
+ return CommonSequenceTypes::ExactlyOneString;
+}
+
+ExpressionVisitorResult::Ptr SimpleContentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qsimplecontentconstructor_p.h b/src/xmlpatterns/expr/qsimplecontentconstructor_p.h
new file mode 100644
index 0000000..bb80b4a
--- /dev/null
+++ b/src/xmlpatterns/expr/qsimplecontentconstructor_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SimpleContentConstructor_H
+#define Patternist_SimpleContentConstructor_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Constructs simple content as specified for attributes in direct
+ * element constructors in XQuery.
+ *
+ * @note Sometimes you want XSLTSimpleContentConstructor.
+ *
+ * @see XSLTSimpleContentConstructor
+ * @see <a href="http://www.w3.org/TR/xquery/#id-attributes">XQuery 1.0:
+ * An XML Query Language, 3.7.1.1 Attributes</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class SimpleContentConstructor : public SingleContainer
+ {
+ public:
+ SimpleContentConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qsinglecontainer.cpp b/src/xmlpatterns/expr/qsinglecontainer.cpp
new file mode 100644
index 0000000..cd280f3
--- /dev/null
+++ b/src/xmlpatterns/expr/qsinglecontainer.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QList>
+
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SingleContainer::SingleContainer(const Expression::Ptr &operand) : m_operand(operand)
+{
+ Q_ASSERT(operand);
+}
+
+Expression::List SingleContainer::operands() const
+{
+ Expression::List list;
+ list.append(m_operand);
+ return list;
+}
+
+void SingleContainer::setOperands(const Expression::List &ops)
+{
+ Q_ASSERT(ops.count() == 1);
+ m_operand = ops.first();
+}
+
+bool SingleContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ rewrite(m_operand, m_operand->compress(context), context);
+
+ return m_operand->isEvaluated();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qsinglecontainer_p.h b/src/xmlpatterns/expr/qsinglecontainer_p.h
new file mode 100644
index 0000000..a55e891
--- /dev/null
+++ b/src/xmlpatterns/expr/qsinglecontainer_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SingleContainer_H
+#define Patternist_SingleContainer_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has exactly one operand.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class SingleContainer : public Expression
+ {
+ public:
+ virtual Expression::List operands() const;
+
+ virtual void setOperands(const Expression::List &operands);
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ protected:
+ SingleContainer(const Expression::Ptr &operand);
+
+ Expression::Ptr m_operand;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qsourcelocationreflection.cpp b/src/xmlpatterns/expr/qsourcelocationreflection.cpp
new file mode 100644
index 0000000..d24b030
--- /dev/null
+++ b/src/xmlpatterns/expr/qsourcelocationreflection.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsourcelocation.h"
+
+#include "qsourcelocationreflection_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QSourceLocation SourceLocationReflection::sourceLocation() const
+{
+ return QSourceLocation();
+}
+
+const SourceLocationReflection *DelegatingSourceLocationReflection::actualReflection() const
+{
+ return m_r->actualReflection();
+}
+
+QString DelegatingSourceLocationReflection::description() const
+{
+ return m_r->description();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qsourcelocationreflection_p.h b/src/xmlpatterns/expr/qsourcelocationreflection_p.h
new file mode 100644
index 0000000..d85c10c
--- /dev/null
+++ b/src/xmlpatterns/expr/qsourcelocationreflection_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SourceLocationReflection_H
+#define Patternist_SourceLocationReflection_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all instances that represents something
+ * at a certain location.
+ *
+ * SourceLocationReflection does not provide the source location itself,
+ * the address to an instance is the mark for it, that in turn can be used
+ * for looking up the source location where that mapping is provided.
+ *
+ * However, this SourceLocationReflection is not itself the mark. The real
+ * mark is retrieved by calling actualReflection(). This mechanism
+ * allows a SourceLocationReflection sub-class to delegate, or be an alias,
+ * for another source location mark.
+ *
+ * If sourceLocation() returns a non-null object, it will be used instead
+ * of looking up via actualReflection().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT SourceLocationReflection
+ {
+ public:
+ inline SourceLocationReflection()
+ {
+ }
+
+ virtual ~SourceLocationReflection()
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const = 0;
+
+ /**
+ * A description of what represents the source code location, for
+ * human consumption. Must be translated, as appropriate.
+ */
+ virtual QString description() const
+ {
+ return QString();
+ }
+
+ virtual QSourceLocation sourceLocation() const;
+
+ private:
+ Q_DISABLE_COPY(SourceLocationReflection)
+ };
+
+ class DelegatingSourceLocationReflection : public SourceLocationReflection
+ {
+ public:
+ inline DelegatingSourceLocationReflection(const SourceLocationReflection *const r) : m_r(r)
+ {
+ Q_ASSERT(r);
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual QString description() const;
+
+ private:
+ const SourceLocationReflection *const m_r;
+ };
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qstaticbaseuristore.cpp b/src/xmlpatterns/expr/qstaticbaseuristore.cpp
new file mode 100644
index 0000000..41b2d02
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticbaseuristore.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qstaticbaseuricontext_p.h"
+
+#include "qstaticbaseuristore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticBaseURIStore::StaticBaseURIStore(const QUrl &baseURI,
+ const Expression::Ptr &operand) : SingleContainer(operand)
+ , m_baseURI(baseURI)
+{
+}
+
+Expression::Ptr StaticBaseURIStore::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const StaticContext::Ptr newContext(new StaticBaseURIContext(context->baseURI().resolved(m_baseURI),
+ context));
+ return m_operand->typeCheck(newContext, reqType);
+}
+
+SequenceType::Ptr StaticBaseURIStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List StaticBaseURIStore::expectedOperandTypes() const
+{
+ SequenceType::List ops;
+ ops.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return ops;
+}
+
+ExpressionVisitorResult::Ptr StaticBaseURIStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qstaticbaseuristore_p.h b/src/xmlpatterns/expr/qstaticbaseuristore_p.h
new file mode 100644
index 0000000..1347eab
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticbaseuristore_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticBaseURIStore_H
+#define Patternist_StaticBaseURIStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A compile time only AST node that changes the static base URI,
+ * used when @c xml:base attributes appears.
+ *
+ * @see StaticBaseURIContext
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class StaticBaseURIStore : public SingleContainer
+ {
+ public:
+ /**
+ * @p baseURI must be valid, not empty, and either relative or
+ * absolute.
+ */
+ StaticBaseURIStore(const QUrl &baseURI,
+ const Expression::Ptr &operand);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const QUrl m_baseURI;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp b/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp
new file mode 100644
index 0000000..1131955
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qstaticcompatibilitycontext_p.h"
+
+#include "qstaticcompatibilitystore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticCompatibilityStore::StaticCompatibilityStore(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+Expression::Ptr StaticCompatibilityStore::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const StaticContext::Ptr newContext(new StaticCompatibilityContext(context));
+ return m_operand->typeCheck(newContext, reqType);
+}
+
+SequenceType::Ptr StaticCompatibilityStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List StaticCompatibilityStore::expectedOperandTypes() const
+{
+ SequenceType::List ops;
+ ops.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return ops;
+}
+
+ExpressionVisitorResult::Ptr StaticCompatibilityStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h b/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h
new file mode 100644
index 0000000..981a177
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_StaticCompatibilityStore_H
+#define Patternist_StaticCompatibilityStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A compile time only AST node that changes the backwareds compatibility mode.
+ * Used for XSL-T 2.0's backwards compatibility mode.
+ *
+ * @see StaticCompatibilityContext
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class StaticCompatibilityStore : public SingleContainer
+ {
+ public:
+ /**
+ * @p baseURI must be valid, not empty, and either relative or
+ * absolute.
+ */
+ StaticCompatibilityStore(const Expression::Ptr &operand);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplate.cpp b/src/xmlpatterns/expr/qtemplate.cpp
new file mode 100644
index 0000000..79afab6
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplate.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdynamiccontextstore_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qtemplate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+const SourceLocationReflection* Template::actualReflection() const
+{
+ return this;
+}
+
+DynamicContext::TemplateParameterHash Template::parametersAsHash() const
+{
+ DynamicContext::TemplateParameterHash retval;
+ const int len = templateParameters.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const VariableDeclaration::Ptr &at = templateParameters.at(i);
+ retval.insert(at->name, at->expression());
+ }
+
+ return retval;
+}
+
+void Template::raiseXTSE0680(const ReportContext::Ptr &context,
+ const QXmlName &name,
+ const SourceLocationReflection *const reflection)
+{
+ context->error(QtXmlPatterns::tr("The parameter %1 is passed, but no corresponding %2 exists.")
+ .arg(formatKeyword(context->namePool(), name),
+ formatKeyword(QLatin1String("xsl:param"))),
+ ReportContext::XTSE0680,
+ reflection);
+}
+
+DynamicContext::Ptr Template::createContext(const TemplateInvoker *const invoker,
+ const DynamicContext::Ptr &context,
+ const bool isCallTemplate) const
+{
+ Q_ASSERT(invoker);
+ Q_ASSERT(context);
+
+ /* We have:
+ * - xsl:params in the target template (if any) which may provide
+ * default values.
+ * - xsl:with-params in the caller (if any) which provides values.
+ *
+ * We need to, for each parameter:
+ * - If the called template provides no default value and the caller
+ * has no value, it's an error
+ * - If the called template has a default value and the caller provides
+ * none, it should be used
+ * - In any case the caller provides a value, it needs to be used.
+ *
+ * Problems to look out for:
+ *
+ * - Each xsl:param is in scope for the subsequent xsl:params. Hence,
+ * the evaluation of one xsl:param can depend on another xsl:param,
+ * and so on
+ * - The focus for xsl:params is different from the focus for
+ * the xsl:with-params
+ * - The xsl:with-params are not in scope for the xsl:params.
+ */
+
+ WithParam::Hash withParams(invoker->withParams());
+
+ /**
+ * Parameters or not, we must in any case create a new stack frame
+ * for the template invocation since otherwise we will trash our existing
+ * variables. Hence it's as with calling user functions.
+ *
+ * This is especially reproducible with recursive functions.
+ */
+ DynamicContext::Ptr newStack(context->createStack());
+
+ /* We have no parameters, and we have no further error checking to
+ * do in the case of not being xsl:apply-templates, so we need to do nothing. */
+ if(templateParameters.isEmpty() && (!isCallTemplate || withParams.isEmpty()))
+ return newStack;
+
+ const DynamicContext::TemplateParameterHash hashedParams(parametersAsHash());
+ DynamicContext::TemplateParameterHash sewnTogether(hashedParams);
+
+ const DynamicContext::TemplateParameterHash::iterator end(sewnTogether.end());
+
+ for(DynamicContext::TemplateParameterHash::iterator it(sewnTogether.begin());
+ it != end;
+ ++it)
+ {
+ Expression::Ptr &param = it.value();
+
+ WithParam::Ptr &withParam = withParams[it.key()];
+
+ if(withParam)
+ param = Expression::Ptr(new DynamicContextStore(withParam->sourceExpression(), context));
+ else if(!param)
+ {
+ /* Ops, no xsl:with-param and no default value to cover up for it.
+ */
+ context->error(QtXmlPatterns::tr("The parameter %1 is required, but no corresponding %2 is supplied.")
+ .arg(formatKeyword(context->namePool(), it.key()),
+ formatKeyword(QLatin1String("xsl:with-param"))),
+ ReportContext::XTSE0690,
+ this);
+ }
+ }
+
+ if(isCallTemplate)
+ {
+ /* Find xsl:with-param that has no corresponding xsl:param. */
+ /* Optimization: candidate for threading? */
+
+ const WithParam::Hash::const_iterator end(withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(withParams.constBegin()); it != end; ++it)
+ {
+ if(!hashedParams.contains(it.key()))
+ raiseXTSE0680(context, it.key(), this);
+ }
+
+ }
+
+ newStack->templateParameterStore() = sewnTogether;
+ return newStack;
+}
+
+void Template::compileParameters(const StaticContext::Ptr &context)
+{
+ Q_ASSERT(context);
+
+ const int len = templateParameters.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const VariableDeclaration::Ptr &at = templateParameters.at(i);
+
+ /* If our value is required, we don't have a default value. */
+ if(at->expression())
+ {
+ // TODO why do we pass in its own type here?
+ at->setExpression(at->expression()->typeCheck(context, at->expression()->staticType()));
+
+ at->setExpression(at->expression()->compress(context));
+ }
+ }
+}
+
+Expression::Properties Template::properties() const
+{
+ return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */
+
+ Expression::Properties collect(body->properties());
+
+ VariableDeclaration::List::const_iterator end(templateParameters.constEnd());
+
+ for(VariableDeclaration::List::const_iterator it(templateParameters.constBegin());
+ it != end;
+ ++it)
+ {
+ if((*it)->expression())
+ collect |= (*it)->expression()->properties();
+ }
+
+ // TODO simplify.
+ return collect & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+Expression::Properties Template::dependencies() const
+{
+ return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */
+
+ Expression::Properties collect(body->dependencies());
+
+ VariableDeclaration::List::const_iterator end(templateParameters.constEnd());
+
+ for(VariableDeclaration::List::const_iterator it(templateParameters.constBegin());
+ it != end;
+ ++it)
+ {
+ if((*it)->expression())
+ collect |= (*it)->expression()->dependencies();
+ }
+
+ return collect & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtemplate_p.h b/src/xmlpatterns/expr/qtemplate_p.h
new file mode 100644
index 0000000..cf00850
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplate_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Template_H
+#define Patternist_Template_H
+
+#include <QSharedData>
+#include <QVector>
+
+#include "qdynamiccontext_p.h"
+#include "qexpression_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qtemplateinvoker_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains data related to a template.
+ *
+ * A Template is associated with a mode, by being housed
+ * inside a TemplateMode instance.
+ *
+ * Template has role very similar to UserFunction.
+ *
+ * @see TemplateMode
+ * @see TemplatePattern
+ * @see UserFunction
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class Template : public QSharedData
+ , public SourceLocationReflection
+
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<Template> Ptr;
+ typedef QVector<Template::Ptr> Vector;
+
+ inline Template(const ImportPrecedence ip,
+ const SequenceType::Ptr &reqType) : importPrecedence(ip)
+ , m_reqType(reqType)
+ {
+ }
+
+ Expression::Ptr body;
+
+ /**
+ * Returns @c this.
+ */
+ virtual const SourceLocationReflection* actualReflection() const;
+
+ const ImportPrecedence importPrecedence;
+
+ VariableDeclaration::List templateParameters;
+
+ /**
+ * If @p isCallTemplate, the caller is @c xsl:call-template, as opposed
+ * to for instance @c xsl:apply-templates. This affects error
+ * reporting.
+ */
+ DynamicContext::Ptr createContext(const TemplateInvoker *const invoker,
+ const DynamicContext::Ptr &context,
+ const bool isCallTemplate) const;
+
+ /**
+ * Since we have our template parameters in templateParameters, we need
+ * this separate step to do the regular phases:
+ * Expression::typeCheck(), and Expression::compress().
+ */
+ void compileParameters(const StaticContext::Ptr &context);
+
+ /**
+ * A value which takes into account the body and its template
+ * parameters.
+ */
+ Expression::Properties properties() const;
+
+ Expression::Properties dependencies() const;
+
+ static void raiseXTSE0680(const ReportContext::Ptr &context,
+ const QXmlName &name,
+ const SourceLocationReflection *const reflection);
+
+ private:
+ DynamicContext::TemplateParameterHash parametersAsHash() const;
+ const SequenceType::Ptr m_reqType;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplateinvoker.cpp b/src/xmlpatterns/expr/qtemplateinvoker.cpp
new file mode 100644
index 0000000..7de8e01
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateinvoker.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtemplateinvoker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TemplateInvoker::TemplateInvoker(const WithParam::Hash &withParams,
+ const QXmlName &name) : CallSite(name)
+ , m_withParams(withParams)
+{
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin()); it != end; ++it)
+ {
+ /* In the case of for instance:
+ * <xsl:with-param name="empty_seq" as="item()"/>
+ *
+ * we have no default expression. */
+ Q_ASSERT(it.value()->sourceExpression());
+ m_operands.append(it.value()->sourceExpression());
+ }
+}
+
+Expression::Ptr TemplateInvoker::compress(const StaticContext::Ptr &context)
+{
+ /* CallSite::compress() may have changed our children, so update
+ * our m_withParams. */
+ const Expression::Ptr me(CallSite::compress(context));
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+ int exprIndex = -1;
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin()); it != end; ++it)
+ {
+ if(it.value()->sourceExpression())
+ {
+ ++exprIndex;
+ it.value()->setSourceExpression(m_operands.at(exprIndex));
+ }
+ }
+
+ return me;
+}
+
+SequenceType::List TemplateInvoker::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ /* We don't return the type of the m_template->templateParameters(), we
+ * return the type of the @c xsl:with-param first. @em After that, we
+ * manually apply the parameter types in typeCheck(). */
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin()); it != end; ++it)
+ {
+ /* We're not guaranteed to have a with-param, we may be using the
+ * default value of the xsl:param. Tunnel parameters may also play
+ * in. */
+ result.append(it.value()->type());
+ }
+
+ return result;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/expr/qtemplateinvoker_p.h b/src/xmlpatterns/expr/qtemplateinvoker_p.h
new file mode 100644
index 0000000..caf0253
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateinvoker_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TemplateInvoker_H
+#define Patternist_TemplateInvoker_H
+
+#include "qcallsite_p.h"
+#include "qwithparam_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for classes that invokes @em templates, such as
+ * CallTemplate and ApplyTemplate.
+ *
+ * TemplateInvoker has the member m_withParams, which is the @c
+ * xsl:with-param instructions of the caller. The definite source for the
+ * expressions is m_withParams, not Expression::operands(). However, the
+ * order of operands() is defined, while m_withParams is not since it's a
+ * hash. Therefore operands() is definite on order.
+ *
+ * TemplateInvoker is intended to be sub-classed.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class TemplateInvoker : public CallSite
+ {
+ public:
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ inline const WithParam::Hash &withParams() const;
+ WithParam::Hash m_withParams;
+
+ /**
+ * This is a bit complicated by that we have two required types, one
+ * specified by @c xsl:param in the template declaration, and one on @c
+ * xsl:with-param.
+ *
+ * @see UserFunctionCallsite::expectedOperandTypes()
+ * @see <a href="http://www.w3.org/TR/xslt20/#with-param">XSL
+ * Transformations (XSLT) Version 2.0, 10.1.1 Passing Parameters to Templates</a>
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+ protected:
+ /**
+ * @p withParams may be empty.
+ */
+ TemplateInvoker(const WithParam::Hash &withParams,
+ const QXmlName &name = QXmlName());
+
+ private:
+ Q_DISABLE_COPY(TemplateInvoker)
+ };
+
+ const WithParam::Hash &TemplateInvoker::withParams() const
+ {
+ return m_withParams;
+ }
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/expr/qtemplatemode.cpp b/src/xmlpatterns/expr/qtemplatemode.cpp
new file mode 100644
index 0000000..976cefd
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatemode.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtemplatemode_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool TemplateMode::lessThanByPriority(const TemplatePattern::Ptr &t1,
+ const TemplatePattern::Ptr &t2)
+{
+ return t1->priority() > t2->priority();
+}
+
+void TemplateMode::finalize()
+{
+ qSort(templatePatterns.begin(), templatePatterns.end(), lessThanByPriority);
+
+ /* Now we have a list of patterns sorted by priority. */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtemplatemode_p.h b/src/xmlpatterns/expr/qtemplatemode_p.h
new file mode 100644
index 0000000..044b405
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatemode_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TemplateMode_H
+#define Patternist_TemplateMode_H
+
+#include <QtCore/QSharedData>
+#include <QXmlName>
+
+#include "qtemplatepattern_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses the data specific to the templates for a certain mode.
+ *
+ * @see Template
+ * @see TemplatePattern
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class Q_AUTOTEST_EXPORT TemplateMode : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<TemplateMode> Ptr;
+
+ inline TemplateMode(const QXmlName &modeName) : m_modeName(modeName)
+ {
+ }
+
+ TemplatePattern::Vector templatePatterns;
+
+ /**
+ * Adds the templates in @p mode to this TemplateMode.
+ *
+ * The existing name remains.
+ */
+ inline void addMode(const TemplateMode::Ptr &mode);
+
+ inline const QXmlName &name() const;
+
+ /**
+ * Orders its templates by priority such that the first lookup always
+ * returns the template with highest priority, and removes templates
+ * shadowed by import precedence.
+ */
+ void finalize();
+
+ private:
+ const QXmlName m_modeName;
+ Q_DISABLE_COPY(TemplateMode)
+
+ /**
+ * Operator for qSort().
+ */
+ static inline bool lessThanByPriority(const TemplatePattern::Ptr &t1,
+ const TemplatePattern::Ptr &t2);
+ };
+
+ const QXmlName &TemplateMode::name() const
+ {
+ return m_modeName;
+ }
+
+ void TemplateMode::addMode(const TemplateMode::Ptr &mode)
+ {
+ templatePatterns += mode->templatePatterns;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplateparameterreference.cpp b/src/xmlpatterns/expr/qtemplateparameterreference.cpp
new file mode 100644
index 0000000..550e39f
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateparameterreference.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qtemplateparameterreference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TemplateParameterReference::TemplateParameterReference(const VariableDeclaration::Ptr &varDecl) : m_varDecl(varDecl)
+{
+}
+
+bool TemplateParameterReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->templateParameterStore()[m_varDecl->name]->evaluateEBV(context);
+}
+
+Item TemplateParameterReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->templateParameterStore()[m_varDecl->name]->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr TemplateParameterReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(!m_varDecl->name.isNull());
+ Q_ASSERT(context->templateParameterStore()[m_varDecl->name]);
+ return context->templateParameterStore()[m_varDecl->name]->evaluateSequence(context);
+}
+
+ExpressionVisitorResult::Ptr TemplateParameterReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties TemplateParameterReference::properties() const
+{
+ return DisableElimination;
+}
+
+SequenceType::Ptr TemplateParameterReference::staticType() const
+{
+ /* We can't use m_varDecl->expression()'s static type here, because
+ * it's the default argument. */
+ if(!m_varDecl->sequenceType)
+ return CommonSequenceTypes::ZeroOrMoreItems;
+ else
+ return m_varDecl->sequenceType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtemplateparameterreference_p.h b/src/xmlpatterns/expr/qtemplateparameterreference_p.h
new file mode 100644
index 0000000..7eb9562
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateparameterreference_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TemplateParameterReference_H
+#define Patternist_TemplateParameterReference_H
+
+#include "qvariabledeclaration_p.h"
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to a template parameter declared with @c xsl:param.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class TemplateParameterReference : public EmptyContainer
+ {
+ public:
+ TemplateParameterReference(const VariableDeclaration::Ptr &varDecl);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+
+ inline const Expression::Ptr &sourceExpression() const;
+ inline const VariableDeclaration::Ptr &variableDeclaration() const;
+
+ private:
+ const VariableDeclaration::Ptr m_varDecl;
+ };
+
+ inline const Expression::Ptr &TemplateParameterReference::sourceExpression() const
+ {
+ return m_varDecl->expression();
+ }
+
+ inline const VariableDeclaration::Ptr &TemplateParameterReference::variableDeclaration() const
+ {
+ return m_varDecl;
+ }
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplatepattern_p.h b/src/xmlpatterns/expr/qtemplatepattern_p.h
new file mode 100644
index 0000000..1ac1c56
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatepattern_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TemplatePattern_H
+#define Patternist_TemplatePattern_H
+
+#include "qtemplate_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses the data necessary for a template pattern.
+ *
+ * A template pattern is the match pattern, but have had each operand to @c
+ * | separated out into a separate TemplatePattern. For instance, the
+ * pattern <tt>a | b | c</tt>, becomes three separate TemplatePattern
+ * instances.
+ *
+ * @see TemplateMode
+ * @see Template
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class TemplatePattern : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<TemplatePattern> Ptr;
+ typedef QVector<Ptr> Vector;
+ typedef int ID;
+
+ inline TemplatePattern(const Expression::Ptr &matchPattern,
+ const PatternPriority pri,
+ const ID id,
+ const Template::Ptr templ);
+
+ inline PatternPriority priority() const;
+ inline const Expression::Ptr &matchPattern() const;
+ inline void setMatchPattern(const Expression::Ptr &pattern);
+ inline const Template::Ptr &templateTarget() const;
+ inline ID id() const;
+
+ /**
+ * This ID is used to ensure that, as 6.4 Conflict Resolution for
+ * Template Rules reads:
+ *
+ * "If the pattern contains multiple alternatives separated by |, then
+ * the template rule is treated equivalently to a set of template
+ * rules, one for each alternative. However, it is not an error if a
+ * node matches more than one of the alternatives."
+ *
+ * For patterns separated by @c |, we have one Template instance for
+ * each alternative, but they all have the same ID, hence if several
+ * alternatives match, we don't flag it as an error if they have the
+ * same ID.
+ */
+ private:
+ Expression::Ptr m_matchPattern;
+ PatternPriority m_priority;
+ ID m_id;
+ Template::Ptr m_templateTarget;
+ Q_DISABLE_COPY(TemplatePattern)
+ };
+
+ TemplatePattern::TemplatePattern(const Expression::Ptr &matchPattern,
+ const PatternPriority pri,
+ const ID id,
+ const Template::Ptr templ) : m_matchPattern(matchPattern)
+ , m_priority(pri)
+ , m_id(id)
+ , m_templateTarget(templ)
+
+ {
+ Q_ASSERT(m_matchPattern);
+ Q_ASSERT(m_templateTarget);
+ }
+
+ const Expression::Ptr &TemplatePattern::matchPattern() const
+ {
+ return m_matchPattern;
+ }
+
+ void TemplatePattern::setMatchPattern(const Expression::Ptr &pattern)
+ {
+ m_matchPattern = pattern;
+ }
+
+ PatternPriority TemplatePattern::priority() const
+ {
+ return m_priority;
+ }
+
+ TemplatePattern::ID TemplatePattern::id() const
+ {
+ return m_id;
+ }
+
+ const Template::Ptr &TemplatePattern::templateTarget() const
+ {
+ return m_templateTarget;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/expr/qtextnodeconstructor.cpp b/src/xmlpatterns/expr/qtextnodeconstructor.cpp
new file mode 100644
index 0000000..bb74079
--- /dev/null
+++ b/src/xmlpatterns/expr/qtextnodeconstructor.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+
+#include "qtextnodeconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TextNodeConstructor::TextNodeConstructor(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+Item TextNodeConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item chars(m_operand->evaluateSingleton(context));
+
+ if(!chars)
+ return Item();
+
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+ const QString &v = chars.stringValue();
+ nodeBuilder->characters(QStringRef(&v));
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void TextNodeConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ if(item)
+ {
+ const QString &v = item.stringValue();
+ receiver->characters(QStringRef(&v));
+ }
+ else
+ receiver->characters(QStringRef());
+}
+
+SequenceType::Ptr TextNodeConstructor::staticType() const
+{
+ if(m_operand->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneTextNode;
+ else
+ return CommonSequenceTypes::ExactlyOneTextNode;
+}
+
+SequenceType::List TextNodeConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties TextNodeConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+TextNodeConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtextnodeconstructor_p.h b/src/xmlpatterns/expr/qtextnodeconstructor_p.h
new file mode 100644
index 0000000..ac20cc7
--- /dev/null
+++ b/src/xmlpatterns/expr/qtextnodeconstructor_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TextNodeConstructor_H
+#define Patternist_TextNodeConstructor_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a text node. This covers both computed and directly constructed
+ * text nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TextNodeConstructor : public SingleContainer
+ {
+ public:
+ TextNodeConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtreatas.cpp b/src/xmlpatterns/expr/qtreatas.cpp
new file mode 100644
index 0000000..8ccfb12
--- /dev/null
+++ b/src/xmlpatterns/expr/qtreatas.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qtypechecker_p.h"
+
+#include "qtreatas_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TreatAs::TreatAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqType) : SingleContainer(operand),
+ m_reqType(reqType)
+{
+ Q_ASSERT(reqType);
+}
+
+Expression::Ptr TreatAs::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(context);
+ Q_ASSERT(reqType);
+
+ /* Apply function conversion with the special error code XPDY0050. After that, we
+ * let the regular typeCheck() function be invoked on the operand before we rewrite
+ * to it. Hence is applyFunctionConversion() called twice, which doesn't break anything,
+ * but indeed is redundant. */
+ const Expression::Ptr treated(TypeChecker::applyFunctionConversion(m_operand,
+ m_reqType,
+ context,
+ ReportContext::XPDY0050));
+ return treated->typeCheck(context, reqType);
+}
+
+ExpressionVisitorResult::Ptr TreatAs::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr TreatAs::staticType() const
+{
+ return m_reqType;
+}
+
+SequenceType::List TreatAs::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtreatas_p.h b/src/xmlpatterns/expr/qtreatas_p.h
new file mode 100644
index 0000000..cf8599c
--- /dev/null
+++ b/src/xmlpatterns/expr/qtreatas_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TreatAs_H
+#define Patternist_TreatAs_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's <tt>treat as</tt> expression.
+ *
+ * TreatAs is always a compile-time class only, and is always deallocated
+ * by re-writing to CardinalityVerifier or ItemVerifier or both, by calling
+ * TypeChecker::applyFunctionConversion().
+ *
+ *
+ * One approach could be to skip instantiating TreatAs and simply let the
+ * return value of TypeChecker::applyFunctionConversion() be inserted into
+ * the AST, but that wouldn't handle type checking the context item
+ * properly, which depends on that the StaticContext have been set by the
+ * parent Expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-treat">XML Path Language
+ * (XPath) 2.0, 3.10.5 Treat</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TreatAs : public SingleContainer
+ {
+ public:
+ /**
+ * Creats a TreatAs where it is checked that the expression @p operand conforms
+ * to the type @p reqType.
+ */
+ TreatAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * This function rewrites always. First the type that this TreatAs expression tests for
+ * is verified. Then, the type the <tt>treat as</tt> expression itself must match, @p reqType,
+ * is verified.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always the SequenceType passed in the constructor to this class. That is, the
+ * SequenceType that the operand must conform to.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const SequenceType::Ptr m_reqType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtriplecontainer.cpp b/src/xmlpatterns/expr/qtriplecontainer.cpp
new file mode 100644
index 0000000..8ffff85
--- /dev/null
+++ b/src/xmlpatterns/expr/qtriplecontainer.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QList>
+
+#include "qtriplecontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TripleContainer::TripleContainer(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Expression::Ptr &operand3) : m_operand1(operand1),
+ m_operand2(operand2),
+ m_operand3(operand3)
+{
+ Q_ASSERT(operand1);
+ Q_ASSERT(operand2);
+ Q_ASSERT(operand3);
+}
+
+Expression::List TripleContainer::operands() const
+{
+ Expression::List result;
+ result.append(m_operand1);
+ result.append(m_operand2);
+ result.append(m_operand3);
+ return result;
+}
+
+void TripleContainer::setOperands(const Expression::List &ops)
+{
+ Q_ASSERT(ops.count() == 3);
+ m_operand1 = ops.first();
+ m_operand2 = ops.at(1);
+ m_operand3 = ops.at(2);
+}
+
+bool TripleContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ rewrite(m_operand1, m_operand1->compress(context), context);
+ rewrite(m_operand2, m_operand2->compress(context), context);
+ rewrite(m_operand3, m_operand3->compress(context), context);
+
+ return m_operand1->isEvaluated() && m_operand2->isEvaluated() && m_operand3->isEvaluated();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtriplecontainer_p.h b/src/xmlpatterns/expr/qtriplecontainer_p.h
new file mode 100644
index 0000000..e9cd249
--- /dev/null
+++ b/src/xmlpatterns/expr/qtriplecontainer_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TripleContainer_H
+#define Patternist_TripleContainer_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has exactly three operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TripleContainer : public Expression
+ {
+ public:
+ virtual Expression::List operands() const;
+ virtual void setOperands(const Expression::List &operands);
+
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ protected:
+ TripleContainer(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Expression::Ptr &operand3);
+
+ Expression::Ptr m_operand1;
+ Expression::Ptr m_operand2;
+ Expression::Ptr m_operand3;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtruthpredicate.cpp b/src/xmlpatterns/expr/qtruthpredicate.cpp
new file mode 100644
index 0000000..0c967d2
--- /dev/null
+++ b/src/xmlpatterns/expr/qtruthpredicate.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qtruthpredicate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TruthPredicate::TruthPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate) : GenericPredicate(sourceExpression,
+ predicate)
+{
+}
+
+SequenceType::List TruthPredicate::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::EBV);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr TruthPredicate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtruthpredicate_p.h b/src/xmlpatterns/expr/qtruthpredicate_p.h
new file mode 100644
index 0000000..1a395bd
--- /dev/null
+++ b/src/xmlpatterns/expr/qtruthpredicate_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TruthPredicate_H
+#define Patternist_TruthPredicate_H
+
+#include "qgenericpredicate_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A predicate which is optimized for filter expressions that
+ * are of type @c xs:boolean.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TruthPredicate : public GenericPredicate
+ {
+ public:
+ /**
+ * Creates a TruthPredicate which filters the items from the @p sourceExpression
+ * through @p predicate.
+ *
+ * This constructor is protected. The proper way to create predicates is via the static
+ * create() function.
+ */
+ TruthPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate);
+
+ inline Item mapToItem(const Item &item, const DynamicContext::Ptr &context) const
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This is practically dead code because it never gets called in GenericPredicate, "
+ "which binds to its own mapToItem for completely legitime reasons.");
+ if(m_operand2->evaluateEBV(context))
+ return item;
+ else
+ return Item();
+ }
+
+ inline Item::Iterator::Ptr map(const Item &item,
+ const DynamicContext::Ptr &context) const
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "I don't expect this function to be called, for the same reasons as above.");
+ if(m_operand2->evaluateEBV(context))
+ return makeSingletonIterator(item);
+ else
+ return CommonValues::emptyIterator;
+ }
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qunaryexpression.cpp b/src/xmlpatterns/expr/qunaryexpression.cpp
new file mode 100644
index 0000000..88419ce
--- /dev/null
+++ b/src/xmlpatterns/expr/qunaryexpression.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qarithmeticexpression_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+#include "qschemanumeric_p.h"
+
+#include "qunaryexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UnaryExpression::UnaryExpression(const AtomicMathematician::Operator op,
+ const Expression::Ptr &operand,
+ const StaticContext::Ptr &context) : ArithmeticExpression(wrapLiteral(CommonValues::IntegerZero, context, operand.data()),
+ op,
+ operand)
+{
+ Q_ASSERT(op == AtomicMathematician::Substract ||
+ op == AtomicMathematician::Add);
+ Q_ASSERT(context);
+}
+
+Item UnaryExpression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ if(operatorID() == AtomicMathematician::Substract)
+ {
+ const Item item(m_operand2->evaluateSingleton(context));
+
+ if(item)
+ return item.as<Numeric>()->toNegated();
+ else
+ return Item();
+ }
+ else
+ return m_operand2->evaluateSingleton(context);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qunaryexpression_p.h b/src/xmlpatterns/expr/qunaryexpression_p.h
new file mode 100644
index 0000000..abc17cb
--- /dev/null
+++ b/src/xmlpatterns/expr/qunaryexpression_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UnaryExpression_H
+#define Patternist_UnaryExpression_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#include "qarithmeticexpression_p.h"
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0 unary expression, <tt>(-|+)ValueExpr</tt>.
+ *
+ * UnaryExpression is implemented by rewriting the expression <tt>operator [expr]</tt>
+ * to the ArithmeticExpression <tt>0 operator [expr]</tt>. For example, the expression
+ * <tt>+3</tt> becomes <tt>0 + 3</tt>, and <tt>-nodetest</tt> becomes <tt>0 - nodetest</tt>.
+ *
+ * On top of that expression ArithmeticExpression does the usual type
+ * checking conversion. The only thing this class do, is to overide
+ * evaluateSingleton() and calls Numeric::toNegated(). The reason this
+ * UnaryExpression is needed at all and that <tt>0 - [expr]</tt> is
+ * insufficent is that <tt>0 - xs:double(0)</tt> needs to return -0,
+ * instead of 0. I know no other difference.
+ *
+ * In most cases the constant propagation optimization rewrites UnaryExpression into
+ * a value, an instance of a sub-class of the Numeric class, wrapped with
+ * Literal.
+ *
+ * Beyond the mathematical implication the unary expression have, it also
+ * have the significant effect that it may invoke type promotion or that an expression
+ * may contain a type error. For example, the expression "+'a string'" contains a type error, since
+ * no unary operator is defined for @c xs:string. This is the reason why the '+' unary
+ * operator isn't ignored.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-arithmetic">XML Path Language
+ * (XPath) 2.0, 3.4 Arithmetic Expressions</a>
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-unary-plus">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators, 6.2.7 op:numeric-unary-plus</a>
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-unary-minus">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators, 6.2.8 op:numeric-unary-minus</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UnaryExpression : public ArithmeticExpression
+ {
+ public:
+ UnaryExpression(const AtomicMathematician::Operator op,
+ const Expression::Ptr &operand,
+ const StaticContext::Ptr &context);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ private:
+ Q_DISABLE_COPY(UnaryExpression)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qunlimitedcontainer.cpp b/src/xmlpatterns/expr/qunlimitedcontainer.cpp
new file mode 100644
index 0000000..d1f4638
--- /dev/null
+++ b/src/xmlpatterns/expr/qunlimitedcontainer.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qunlimitedcontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UnlimitedContainer::UnlimitedContainer(const Expression::List &ops) : m_operands(ops)
+{
+}
+
+void UnlimitedContainer::setOperands(const Expression::List &list)
+{
+ m_operands = list;
+}
+
+Expression::List UnlimitedContainer::operands() const
+{
+ return m_operands;
+}
+
+bool UnlimitedContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ const Expression::List::iterator end(m_operands.end());
+ Expression::List::iterator it(m_operands.begin());
+ int evaled = 0;
+
+ for(; it != end; ++it)
+ {
+ Q_ASSERT((*it));
+ rewrite((*it), (*it)->compress(context), context);
+ if((*it)->isEvaluated())
+ ++evaled;
+ }
+
+ return evaled == m_operands.count();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qunlimitedcontainer_p.h b/src/xmlpatterns/expr/qunlimitedcontainer_p.h
new file mode 100644
index 0000000..1c032f0
--- /dev/null
+++ b/src/xmlpatterns/expr/qunlimitedcontainer_p.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UnlimitedContainer_H
+#define Patternist_UnlimitedContainer_H
+
+#include <QList>
+#include "qexpression_p.h"
+#include "qgenericsequencetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has any amount of operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UnlimitedContainer : public Expression
+ {
+ public:
+ /**
+ * Creates an UnlimitedContainer containing the operands @p operands. @p operands
+ * may be empty.
+ */
+ UnlimitedContainer(const Expression::List &operands = Expression::List());
+
+ virtual void setOperands(const Expression::List &list);
+
+ virtual Expression::List operands() const;
+
+ /**
+ * @note This function cannot be called before setOperands is called.
+ */
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ /**
+ * Tells how operandsUnionType() should compute the cardinality of
+ * its children.
+ *
+ * This type is public because of a bug in the HP-UX aCC compiler.
+ */
+ enum CardinalityComputation
+ {
+ ProductOfCardinality,
+ UnionOfCardinality
+ };
+
+ protected:
+ /**
+ * Computes and returns the union type of all the Expression instances
+ * in this Expression's operands.
+ *
+ * This implementation is placed inside because CardinalityComputation
+ * can't be referenced from the outside(in conforming compilers).
+ */
+ template<CardinalityComputation suppliedCard>
+ inline
+ SequenceType::Ptr operandsUnionType() const
+ {
+ Q_ASSERT(suppliedCard == ProductOfCardinality || suppliedCard == UnionOfCardinality);
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List::const_iterator it(m_operands.constBegin());
+
+ /* Load the first one, and jump over it in the loop. */
+ SequenceType::Ptr t(m_operands.first()->staticType());
+ ItemType::Ptr type(t->itemType());
+ Cardinality card(t->cardinality());
+ ++it;
+
+ for(; it != end; ++it)
+ {
+ t = (*it)->staticType();
+ type |= t->itemType();
+
+ /* Since this function is a template function, it doesn't
+ * hurt performance that this test is inside the loop. */
+ if(suppliedCard == ProductOfCardinality)
+ card += t->cardinality();
+ else
+ card |= t->cardinality();
+ }
+
+ return makeGenericSequenceType(type, card);
+ }
+
+ Expression::List m_operands;
+ };
+
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qunresolvedvariablereference.cpp b/src/xmlpatterns/expr/qunresolvedvariablereference.cpp
new file mode 100644
index 0000000..68c974e
--- /dev/null
+++ b/src/xmlpatterns/expr/qunresolvedvariablereference.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qunresolvedvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UnresolvedVariableReference::UnresolvedVariableReference(const QXmlName &name) : m_name(name)
+{
+ Q_ASSERT(!m_name.isNull());
+}
+
+Expression::Ptr UnresolvedVariableReference::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* We may be called before m_replacement is called, when we're part of a
+ * function body whose type checking is performed for. See
+ * UserFunctionCallsite::typeCheck(). */
+ if(m_replacement)
+ return m_replacement->typeCheck(context, reqType);
+ else
+ return EmptyContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr UnresolvedVariableReference::staticType() const
+{
+ /* We may be called by xmlpatternsview before the typeCheck() stage. */
+ if(m_replacement)
+ return m_replacement->staticType();
+ else
+ return CommonSequenceTypes::ZeroOrMoreItems;
+}
+
+SequenceType::List UnresolvedVariableReference::expectedOperandTypes() const
+{
+ return SequenceType::List();
+}
+
+ExpressionVisitorResult::Ptr UnresolvedVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID UnresolvedVariableReference::id() const
+{
+ return IDUnresolvedVariableReference;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qunresolvedvariablereference_p.h b/src/xmlpatterns/expr/qunresolvedvariablereference_p.h
new file mode 100644
index 0000000..d32fb0a
--- /dev/null
+++ b/src/xmlpatterns/expr/qunresolvedvariablereference_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UnresolvedVariableReference_H
+#define Patternist_UnresolvedVariableReference_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Compile time only AST-node which is a marker for variable
+ * references whose declaration has not yet appeared in the source code.
+ *
+ * This can not appear in XQuery, but can in XSL-T.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class Q_AUTOTEST_EXPORT UnresolvedVariableReference : public EmptyContainer
+ {
+ public:
+ UnresolvedVariableReference(const QXmlName &name);
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ inline void bindTo(const Expression::Ptr &body);
+
+ inline Expression::Ptr replacement() const;
+
+ private:
+ const QXmlName m_name;
+ Expression::Ptr m_replacement;
+ };
+
+ void UnresolvedVariableReference::bindTo(const Expression::Ptr &body)
+ {
+ Q_ASSERT(body);
+ m_replacement = body;
+ }
+
+ Expression::Ptr UnresolvedVariableReference::replacement() const
+ {
+ Q_ASSERT(m_replacement);
+ return m_replacement;
+ }
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/quserfunction.cpp b/src/xmlpatterns/expr/quserfunction.cpp
new file mode 100644
index 0000000..f440b61
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunction.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "quserfunction_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UserFunction::UserFunction(const FunctionSignature::Ptr &sign,
+ const Expression::Ptr &b,
+ const VariableSlotID slotOffset,
+ const VariableDeclaration::List &varDecls) : m_signature(sign),
+ m_body(b),
+ m_slotOffset(slotOffset),
+ m_argumentDeclarations(varDecls)
+{
+ Q_ASSERT(m_signature);
+ Q_ASSERT(m_body);
+ Q_ASSERT(m_slotOffset > -2);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/quserfunction_p.h b/src/xmlpatterns/expr/quserfunction_p.h
new file mode 100644
index 0000000..938a1d9
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunction_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UserFunction_H
+#define Patternist_UserFunction_H
+
+template<typename T> class QList;
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+#include "qfunctionsignature_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A function created with XQuery's <tt>declare function</tt> declaration.
+ *
+ * @see UserFunctionCall
+ * @see ArgumentReference
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UserFunction : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<UserFunction> Ptr;
+ typedef QList<UserFunction::Ptr> List;
+
+ /**
+ * If @p slotOffset is -1, it means this function has no arguments.
+ */
+ UserFunction(const FunctionSignature::Ptr &signature,
+ const Expression::Ptr &body,
+ const VariableSlotID slotOffset,
+ const VariableDeclaration::List &varDecls);
+
+ inline const Expression::Ptr &body() const;
+ inline void setBody(const Expression::Ptr &newBody);
+ inline FunctionSignature::Ptr signature() const;
+ inline VariableSlotID expressionSlotOffset() const;
+ inline VariableDeclaration::List argumentDeclarations() const;
+
+ private:
+ const FunctionSignature::Ptr m_signature;
+ Expression::Ptr m_body;
+ const VariableSlotID m_slotOffset;
+ const VariableDeclaration::List m_argumentDeclarations;
+ };
+
+ inline const Expression::Ptr &UserFunction::body() const
+ {
+ return m_body;
+ }
+
+ inline FunctionSignature::Ptr UserFunction::signature() const
+ {
+ return m_signature;
+ }
+
+ inline VariableSlotID UserFunction::expressionSlotOffset() const
+ {
+ return m_slotOffset;
+ }
+
+ inline VariableDeclaration::List UserFunction::argumentDeclarations() const
+ {
+ return m_argumentDeclarations;
+ }
+
+ void UserFunction::setBody(const Expression::Ptr &newBody)
+ {
+ m_body = newBody;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/quserfunctioncallsite.cpp b/src/xmlpatterns/expr/quserfunctioncallsite.cpp
new file mode 100644
index 0000000..4e81484
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunctioncallsite.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdynamiccontextstore_p.h"
+#include "qevaluationcache_p.h"
+
+#include "quserfunctioncallsite_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UserFunctionCallsite::UserFunctionCallsite(const QXmlName nameP,
+ const FunctionSignature::Arity ar) : CallSite(nameP)
+ , m_arity(ar)
+ , m_expressionSlotOffset(-2)
+
+{
+}
+
+Item::Iterator::Ptr UserFunctionCallsite::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_body->evaluateSequence(bindVariables(context));
+}
+
+Item UserFunctionCallsite::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_body->evaluateSingleton(bindVariables(context));
+}
+
+bool UserFunctionCallsite::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_body->evaluateEBV(bindVariables(context));
+}
+
+void UserFunctionCallsite::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ m_body->evaluateToSequenceReceiver(bindVariables(context));
+}
+
+DynamicContext::Ptr UserFunctionCallsite::bindVariables(const DynamicContext::Ptr &context) const
+{
+ const DynamicContext::Ptr stackContext(context->createStack());
+ Q_ASSERT(stackContext);
+
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List::const_iterator it(m_operands.constBegin());
+
+ VariableSlotID slot = m_expressionSlotOffset;
+
+ for(; it != end; ++it)
+ {
+ stackContext->setExpressionVariable(slot,
+ Expression::Ptr(new DynamicContextStore(*it, context)));
+ ++slot;
+ }
+
+ return stackContext;
+}
+
+SequenceType::List UserFunctionCallsite::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ if(m_functionDeclaration)
+ {
+ const FunctionArgument::List args(m_functionDeclaration->signature()->arguments());
+ const FunctionArgument::List::const_iterator end(args.constEnd());
+ FunctionArgument::List::const_iterator it(args.constBegin());
+
+ for(; it != end; ++it)
+ result.append((*it)->type());
+ }
+ else
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+
+ return result;
+}
+
+Expression::Ptr UserFunctionCallsite::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* The parser calls TypeChecker::applyFunctionConversion() on user function
+ * bodies, possibly indirectly, before all function call sites have been
+ * resolved. Hence it's possible that we're called before before the usual
+ * typeCheck() pass, and hence before we have been resolved/checked and
+ * subsequently m_functionDeclaration set. Therefore, encounter for that below.
+ *
+ * UnresolvedVariableReference::typeCheck() has the same dilemma.
+ */
+
+ /* Ensure that the return value of the function is properly
+ * converted/does match from where it is called(which is here). */
+ if(isRecursive() || !m_functionDeclaration)
+ return CallSite::typeCheck(context, reqType);
+ else
+ {
+ /* Update, such that we use a recent version of the body that has typeCheck()
+ * and compress() rewrites included. */
+ m_body = m_functionDeclaration->body();
+
+ /* Note, we can't assign to m_functionDeclaration->body() because UserFunction can apply
+ * to several different callsites. Hence we need our own version. */
+ m_body = m_body->typeCheck(context, reqType);
+
+ /* We just act as a pipe for m_body, so we don't have to typecheck ourselves. However,
+ * the arguments must match the function declaration. */
+ typeCheckOperands(context);
+ return Expression::Ptr(this);
+ }
+}
+
+Expression::Ptr UserFunctionCallsite::compress(const StaticContext::Ptr &context)
+{
+ if(!isRecursive())
+ rewrite(m_body, m_body->compress(context), context);
+
+ return CallSite::compress(context);
+}
+
+Expression::Properties UserFunctionCallsite::properties() const
+{
+ return DisableElimination;
+}
+
+SequenceType::Ptr UserFunctionCallsite::staticType() const
+{
+ /* Our return type, is the static type of the function body. We could have also used
+ * m_functionDeclaration->signature()->returnType(), but it doesn't get updated
+ * when function conversion is applied.
+ * We can't use m_body's type if we're recursive, because m_body computes its type
+ * from its children, and we're at least one of the children. Hence, we would
+ * recurse infinitely if we did.
+ *
+ * m_body can be null here if we're called before setSource().
+ */
+ if(isRecursive() || !m_body)
+ return CommonSequenceTypes::ZeroOrMoreItems; // TODO use the declaration, it can have a type explicitly.
+ else
+ return m_body->staticType();
+}
+
+ExpressionVisitorResult::Ptr UserFunctionCallsite::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID UserFunctionCallsite::id() const
+{
+ return IDUserFunctionCallsite;
+}
+
+bool UserFunctionCallsite::isSignatureValid(const FunctionSignature::Ptr &sign) const
+{
+ Q_ASSERT(sign);
+
+ return sign->name() == name()
+ &&
+ sign->isArityValid(m_arity);
+}
+
+bool UserFunctionCallsite::configureRecursion(const CallTargetDescription::Ptr &sign)
+{
+ Q_ASSERT(sign);
+
+ setIsRecursive(isSignatureValid(sign));
+ return isRecursive();
+}
+
+void UserFunctionCallsite::setSource(const UserFunction::Ptr &userFunction,
+ const VariableSlotID cacheSlotOffset)
+{
+ m_functionDeclaration = userFunction;
+ m_body = userFunction->body();
+ m_expressionSlotOffset = userFunction->expressionSlotOffset();
+
+ const int len = m_operands.size();
+
+ const VariableDeclaration::List varDecls(userFunction->argumentDeclarations());
+
+ for(int i = 0; i < len; ++i)
+ {
+ /* We don't want evaluation caches for range variables, it's not necessary since
+ * the item is already cached in DynamicContext::rangeVariable(). */
+ if(m_operands.at(i)->is(IDRangeVariableReference))
+ continue;
+
+ /* Note that we pass in cacheSlotOffset + i here instead of varDecls.at(i)->slot since
+ * we want independent caches for each callsite. */
+ m_operands[i] = Expression::Ptr(new EvaluationCache<false>(m_operands.at(i),
+ varDecls.at(i),
+ cacheSlotOffset + i));
+ }
+}
+
+FunctionSignature::Arity UserFunctionCallsite::arity() const
+{
+ return m_arity;
+}
+
+CallTargetDescription::Ptr UserFunctionCallsite::callTargetDescription() const
+{
+ return m_functionDeclaration->signature();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/quserfunctioncallsite_p.h b/src/xmlpatterns/expr/quserfunctioncallsite_p.h
new file mode 100644
index 0000000..db6a661
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunctioncallsite_p.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UserFunctionCallsite_H
+#define Patternist_UserFunctionCallsite_H
+
+#include "qcallsite_p.h"
+#include "qfunctionsignature_p.h"
+#include "qunlimitedcontainer_p.h"
+#include "quserfunction_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Performs a call to a UserFunction.
+ *
+ * UserFunctionCallsite is the call site to a function that has been
+ * declared in the query using <tt>declare function</tt>. That is, it is
+ * never used for builtin functions such as <tt>fn:count()</tt>.
+ *
+ * @see UserFunction
+ * @see ArgumentReference
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UserFunctionCallsite : public CallSite
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<UserFunctionCallsite> Ptr;
+ typedef QList<UserFunctionCallsite::Ptr> List;
+
+ UserFunctionCallsite(const QXmlName name,
+ const FunctionSignature::Arity arity);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * We call compress on our body.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual Expression::Properties properties() const;
+
+ /**
+ * @short Returns the types declared in the function declaration.
+ *
+ * @see CallTemplate::expectedOperandTypes()
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always IDUserFunctionCallsite.
+ */
+ virtual ID id() const;
+
+ /**
+ * If @p slotOffset is -1, it means this function has no arguments.
+ */
+ void setSource(const UserFunction::Ptr &userFunction,
+ const VariableSlotID cacheSlotOffset);
+
+ /**
+ * @returns @c true, if a function definition with signature @p sign
+ * would be valid to call from this callsite, otherwise @c false.
+ */
+ bool isSignatureValid(const FunctionSignature::Ptr &sign) const;
+
+ FunctionSignature::Arity arity() const;
+
+ inline Expression::Ptr body() const
+ {
+ return m_body;
+ }
+
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign);
+ virtual CallTargetDescription::Ptr callTargetDescription() const;
+
+ private:
+ /**
+ * Creates a new context sets the arguments, and returns it.
+ */
+ DynamicContext::Ptr bindVariables(const DynamicContext::Ptr &context) const;
+
+ const FunctionSignature::Arity m_arity;
+ /**
+ * The reason this variable, as well as others, aren't const, is that
+ * the binding to the actual function, is resolved after this
+ * UserFunctionCallsite has been created.
+ */
+ VariableSlotID m_expressionSlotOffset;
+
+ /**
+ * @note This may be different from m_functionDeclaration->body(). It
+ * may differ on a per-callsite basis.
+ */
+ Expression::Ptr m_body;
+ UserFunction::Ptr m_functionDeclaration;
+ };
+
+ /**
+ * @short Formats UserFunctionCallsite.
+ *
+ * @relates UserFunctionCallsite
+ */
+ static inline QString formatFunction(const UserFunctionCallsite::Ptr &func)
+ {
+ Q_UNUSED(func);
+ // TODO TODO TODO
+ // TODO Make UserFunctionCallsite always use a FunctionSignature
+ return QLatin1String("<span class='XQuery-function'>") +
+ QString() +
+ //escape(func->name()->toString()) +
+ QLatin1String("</span>");
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvalidate.cpp b/src/xmlpatterns/expr/qvalidate.cpp
new file mode 100644
index 0000000..8071b32
--- /dev/null
+++ b/src/xmlpatterns/expr/qvalidate.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qmultiitemtype_p.h"
+#include "qtypechecker_p.h"
+
+#include "qvalidate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr Validate::create(const Expression::Ptr &operandNode,
+ const Mode validationMode,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(operandNode);
+ Q_ASSERT(validationMode == Lax || validationMode == Strict);
+ Q_ASSERT(context);
+ Q_UNUSED(validationMode);
+ Q_UNUSED(context);
+
+ ItemType::List tList;
+ tList.append(BuiltinTypes::element);
+ tList.append(BuiltinTypes::document);
+
+ const SequenceType::Ptr elementOrDocument(makeGenericSequenceType(ItemType::Ptr(new MultiItemType(tList)),
+ Cardinality::exactlyOne()));
+
+
+ return TypeChecker::applyFunctionConversion(operandNode,
+ elementOrDocument,
+ context,
+ ReportContext::XQTY0030);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvalidate_p.h b/src/xmlpatterns/expr/qvalidate_p.h
new file mode 100644
index 0000000..10910cd
--- /dev/null
+++ b/src/xmlpatterns/expr/qvalidate_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Validate_H
+#define Patternist_Validate_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Handles XQuery 1.0's <tt>validate</tt> expression.
+ *
+ * This class is currently not used. The Schema Validation Feature is not supported.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-validate">XQuery 1.0: An XML
+ * Query Language, 3.13 Validate Expressions</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#id-schema-validation-feature">XQuery 1.0: An
+ * XML Query Language, 5.2.2 Schema Validation Feature</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Validate
+ {
+ public:
+
+ /**
+ * Represents the validation mode.
+ */
+ enum Mode
+ {
+ Lax = 1,
+ Strict
+ };
+
+ /**
+ * Creates the necessary Expression instances
+ * that validates the operand node @p operandNode in mode @p validationMode,
+ * and returns it.
+ */
+ static Expression::Ptr create(const Expression::Ptr &operandNode,
+ const Mode validationMode,
+ const StaticContext::Ptr &context);
+ private:
+ Validate();
+ Q_DISABLE_COPY(Validate)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvaluecomparison.cpp b/src/xmlpatterns/expr/qvaluecomparison.cpp
new file mode 100644
index 0000000..fd0e51b
--- /dev/null
+++ b/src/xmlpatterns/expr/qvaluecomparison.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qoptimizationpasses_p.h"
+
+#include "qvaluecomparison_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ValueComparison::ValueComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2) : PairContainer(op1, op2),
+ m_operator(op)
+{
+}
+
+Item ValueComparison::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item it1(m_operand1->evaluateSingleton(context));
+ if(!it1)
+ return Item();
+
+ const Item it2(m_operand2->evaluateSingleton(context));
+ if(!it2)
+ return Item();
+
+ return Boolean::fromValue(flexibleCompare(it1, it2, context));
+}
+
+Expression::Ptr ValueComparison::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+ const ItemType::Ptr t1(m_operand1->staticType()->itemType());
+ const ItemType::Ptr t2(m_operand2->staticType()->itemType());
+ Q_ASSERT(t1);
+ Q_ASSERT(t2);
+
+ if(*CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ return EmptySequence::create(this, context);
+ }
+ else
+ {
+ prepareComparison(fetchComparator(t1, t2, context));
+
+ return me;
+ }
+}
+
+Expression::Ptr ValueComparison::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ if(isCaseInsensitiveCompare(m_operand1, m_operand2))
+ useCaseInsensitiveComparator();
+
+ return me;
+}
+
+bool ValueComparison::isCaseInsensitiveCompare(Expression::Ptr &op1, Expression::Ptr &op2)
+{
+ Q_ASSERT(op1);
+ Q_ASSERT(op2);
+
+ const ID iD = op1->id();
+
+ if((iD == IDLowerCaseFN || iD == IDUpperCaseFN) && iD == op2->id())
+ {
+ /* Both are either fn:lower-case() or fn:upper-case(). */
+
+ /* Replace the calls to the functions with its operands. */
+ op1 = op1->operands().first();
+ op2 = op2->operands().first();
+
+ return true;
+ }
+ else
+ return false;
+}
+
+OptimizationPass::List ValueComparison::optimizationPasses() const
+{
+ return OptimizationPasses::comparisonPasses;
+}
+
+SequenceType::List ValueComparison::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ return result;
+}
+
+SequenceType::Ptr ValueComparison::staticType() const
+{
+ if(m_operand1->staticType()->cardinality().allowsEmpty() ||
+ m_operand2->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneBoolean;
+ else
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr ValueComparison::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ValueComparison::id() const
+{
+ return IDValueComparison;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvaluecomparison_p.h b/src/xmlpatterns/expr/qvaluecomparison_p.h
new file mode 100644
index 0000000..3aa9f5f
--- /dev/null
+++ b/src/xmlpatterns/expr/qvaluecomparison_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ValueComparison_H
+#define Patternist_ValueComparison_H
+
+#include "qatomiccomparator_p.h"
+#include "qpaircontainer_p.h"
+#include "qcomparisonplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0 value comparions, such as the <tt>eq</tt> operator.
+ *
+ * ComparisonPlatform is inherited with @c protected scope because ComparisonPlatform
+ * must access members of ValueComparison.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-value-comparisons">XML Path Language
+ * (XPath) 2.0, 3.5.1 Value Comparisons</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ValueComparison : public PairContainer,
+ public ComparisonPlatform<ValueComparison, true>
+ {
+ public:
+ ValueComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneBoolean
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns IDValueComparison
+ */
+ virtual ID id() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ /**
+ * Overridden to optimize case-insensitive compares.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns the operator that this ValueComparison is using.
+ */
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return m_operator;
+ }
+
+ /**
+ * It is considered that the string value from @p op1 will be compared against @p op2. This
+ * function determines whether the user intends the comparison to be case insensitive. If
+ * that is the case @c true is returned, and the operands are re-written appropriately.
+ *
+ * This is a helper function for Expression classes that compares strings.
+ *
+ * @see ComparisonPlatform::useCaseInsensitiveComparator()
+ */
+ static bool isCaseInsensitiveCompare(Expression::Ptr &op1, Expression::Ptr &op2);
+
+ private:
+ const AtomicComparator::Operator m_operator;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvariabledeclaration.cpp b/src/xmlpatterns/expr/qvariabledeclaration.cpp
new file mode 100644
index 0000000..2f5a72e
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariabledeclaration.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool VariableDeclaration::contains(const VariableDeclaration::List &list,
+ const QXmlName &lookup)
+{
+ VariableDeclaration::List::const_iterator it(list.constBegin());
+ const VariableDeclaration::List::const_iterator end(list.constEnd());
+
+ for(; it != end; ++it)
+ {
+ if((*it)->name == lookup)
+ return true;
+ }
+
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvariabledeclaration_p.h b/src/xmlpatterns/expr/qvariabledeclaration_p.h
new file mode 100644
index 0000000..a2430a8
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariabledeclaration_p.h
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_VariableDeclaration_H
+#define Patternist_VariableDeclaration_H
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QStack;
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a declared variable. Only used at
+ * the compilation stage.
+ *
+ * @see FunctionArgument
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class VariableDeclaration : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<VariableDeclaration> Ptr;
+ typedef QStack<VariableDeclaration::Ptr> Stack;
+ typedef QList<VariableDeclaration::Ptr> List;
+
+ /**
+ * @short The key is the variable name.
+ */
+ typedef QHash<QXmlName, VariableDeclaration::Ptr> Hash;
+
+ enum Type
+ {
+ RangeVariable,
+ ExpressionVariable,
+ FunctionArgument,
+ PositionalVariable,
+ TemplateParameter,
+
+ /**
+ * A global variable is always an external variable, but it is
+ * cached differently.
+ *
+ * @see DynamicContext::globalItemCacheCell()
+ */
+ GlobalVariable,
+
+ /**
+ * External variables doesn't use slots, that's a big difference
+ * compared to the other types.
+ */
+ ExternalVariable
+ };
+
+ /**
+ * Creates a VariableDeclaration.
+ *
+ * @p sourceExpr and @p seqType may be @c null.
+ */
+ VariableDeclaration(const QXmlName n,
+ const VariableSlotID varSlot,
+ const Type t,
+ const SequenceType::Ptr &seqType) : name(n)
+ , slot(varSlot)
+ , type(t)
+ , sequenceType(seqType)
+ , canSourceRewrite(true)
+ {
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(t == ExternalVariable || t == TemplateParameter || varSlot > -1);
+ }
+
+ inline bool isUsed() const
+ {
+ return !references.isEmpty();
+ }
+
+ inline const Expression::Ptr &expression() const
+ {
+ return m_expression;
+ }
+
+ inline void setExpression(const Expression::Ptr &expr)
+ {
+ m_expression = expr;
+ }
+
+ /**
+ * @short Returns how many times this variable is used.
+ */
+ inline bool usedByMany() const
+ {
+ return references.count() > 1;
+ }
+
+ /**
+ * @short Returns @c true if @p list contains @p lookup.
+ */
+ static bool contains(const VariableDeclaration::List &list,
+ const QXmlName &lookup);
+
+ const QXmlName name;
+ const VariableSlotID slot;
+ const Type type;
+
+ /**
+ * The declared type of the variable. What the value might be, depends
+ * on the context which VariableDeclaration is used in. Note that
+ * sequenceType is hence not in anyway obligated to the type of
+ * expression().
+ */
+ const SequenceType::Ptr sequenceType;
+ VariableReference::List references;
+
+ /**
+ * @short Whether a reference can rewrite itself to expression().
+ *
+ * The default value is @c true.
+ */
+ bool canSourceRewrite;
+
+ private:
+ Expression::Ptr m_expression;
+ Q_DISABLE_COPY(VariableDeclaration)
+ };
+
+ /**
+ * @short Formats @p var appropriately for display.
+ *
+ * @relates VariableDeclaration
+ */
+ static inline QString formatKeyword(const VariableDeclaration::Ptr &var,
+ const NamePool::Ptr &np)
+ {
+ Q_ASSERT(var);
+ Q_ASSERT(np);
+ return formatKeyword(np->displayName(var->name));
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvariablereference.cpp b/src/xmlpatterns/expr/qvariablereference.cpp
new file mode 100644
index 0000000..5281820
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariablereference.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+VariableReference::VariableReference(const VariableSlotID slotP) : m_varSlot(slotP)
+{
+ Q_ASSERT(m_varSlot > -1);
+}
+
+Expression::Properties VariableReference::properties() const
+{
+ return DisableElimination;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvariablereference_p.h b/src/xmlpatterns/expr/qvariablereference_p.h
new file mode 100644
index 0000000..fca6fdd
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariablereference_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_VariableReference_H
+#define Patternist_VariableReference_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QList;
+
+namespace QPatternist
+{
+ /**
+ * @short Baseclass for classes being references to variables.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class VariableReference : public EmptyContainer
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<VariableReference> Ptr;
+ typedef QList<VariableReference::Ptr> List;
+
+ /**
+ * Creates a VariableReference.
+ *
+ * @param slot must be a valid slot. That is, zero or larger.
+ */
+ VariableReference(const VariableSlotID slot);
+
+ /**
+ * @returns the slot that this reference communicates through.
+ *
+ * This is a slot in the DynamicContext. Which one, depends on the
+ * type, which this VariableReference does not have information about.
+ * For instance, it could DynamicContext::expressionVariable() or
+ * DynamicContext::rangeVariable().
+ */
+ inline VariableSlotID slot() const;
+
+ /**
+ * @returns DisableElimination
+ */
+ virtual Properties properties() const;
+
+ private:
+ /**
+ * The slot. Same as returned by slot().
+ *
+ * This variable is not called m_slot, because that creates a weird
+ * compiler error on hpuxi-acc. See the preprocessor output. EvaluationCache::m_varSlot
+ * is a similar workaround.
+ */
+ const VariableSlotID m_varSlot;
+ };
+
+ inline VariableSlotID VariableReference::slot() const
+ {
+ return m_varSlot;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qwithparam_p.h b/src/xmlpatterns/expr/qwithparam_p.h
new file mode 100644
index 0000000..7f8b542
--- /dev/null
+++ b/src/xmlpatterns/expr/qwithparam_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TemplateParam_H
+#define Patternist_TemplateParam_H
+
+#include "qfunctionargument_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Carries meta data for @c xsl:with-param as encountered in
+ * template callsites such as @c xsl:call-template and @c
+ * xsl:apply-templates.
+ *
+ * WithParam is similar to FunctionArgument, but has in addition a default
+ * value in the form of an Expression.
+ *
+ * @since 4.5
+ * @ingroup Patternist_expressions
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class WithParam : public FunctionArgument
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<WithParam> Ptr;
+ typedef QHash<QXmlName, Ptr> Hash;
+
+ /**
+ * @p sourceExpression can not be @c null.
+ */
+ inline WithParam(const QXmlName name,
+ const SequenceType::Ptr &type,
+ const Expression::Ptr &sourceExpression);
+
+ inline void setSourceExpression(const Expression::Ptr &expr)
+ {
+ Q_ASSERT(expr);
+ m_sourceExpression = expr;
+ }
+
+ /**
+ * @short Returns the expression which is the source the value for this
+ * parameter.
+ *
+ * Guaranteed to never be @c null.
+ */
+ inline Expression::Ptr sourceExpression() const
+ {
+ return m_sourceExpression;
+ }
+
+ private:
+ Expression::Ptr m_sourceExpression;
+ };
+
+ WithParam::WithParam(const QXmlName name,
+ const SequenceType::Ptr &type,
+ const Expression::Ptr &sourceExpression) : FunctionArgument(name, type)
+ , m_sourceExpression(sourceExpression)
+ {
+ Q_ASSERT(m_sourceExpression);
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp b/src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp
new file mode 100644
index 0000000..e69dc5d
--- /dev/null
+++ b/src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicstring_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "qxsltsimplecontentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XSLTSimpleContentConstructor::XSLTSimpleContentConstructor(const Expression::Ptr &source) : SimpleContentConstructor(source)
+{
+}
+
+QString XSLTSimpleContentConstructor::processItem(const Item &item,
+ bool &discard,
+ bool &isText)
+{
+ if(item.isNode())
+ {
+ isText = (item.asNode().kind() == QXmlNodeModelIndex::Text);
+
+ if(isText)
+ {
+ const QString value(item.stringValue());
+
+ /* "1. Zero-length text nodes in the sequence are discarded." */
+ discard = value.isEmpty();
+ return value;
+ }
+ else
+ {
+ Item::Iterator::Ptr it(item.sequencedTypedValue()); /* Atomic values. */
+ Item next(it->next());
+ QString result;
+
+ if(next)
+ result = next.stringValue();
+
+ next = it->next();
+
+ while(next)
+ {
+ result += next.stringValue();
+ result += QLatin1Char(' ');
+ next = it->next();
+ }
+
+ return result;
+ }
+ }
+ else
+ {
+ discard = false;
+ isText = false;
+ return item.stringValue();
+ }
+}
+
+Item XSLTSimpleContentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+
+ Item next(it->next());
+ QString result;
+
+ bool previousIsText = false;
+ bool discard = false;
+
+ if(next)
+ {
+ const QString unit(processItem(next, discard, previousIsText));
+
+ if(!discard)
+ result = unit;
+
+ next = it->next();
+ }
+ else
+ return Item();
+
+ while(next)
+ {
+ bool currentIsText = false;
+ const QString unit(processItem(next, discard, currentIsText));
+
+ if(!discard)
+ {
+ /* "Adjacent text nodes in the sequence are merged into a single text
+ * node." */
+ if(previousIsText && currentIsText)
+ ;
+ else
+ result += QLatin1Char(' ');
+
+ result += unit;
+ }
+
+ next = it->next();
+ previousIsText = currentIsText;
+ }
+
+ return AtomicString::fromValue(result);
+}
+
+SequenceType::List XSLTSimpleContentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr XSLTSimpleContentConstructor::staticType() const
+{
+ return CommonSequenceTypes::ZeroOrOneString;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h b/src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h
new file mode 100644
index 0000000..853a38b
--- /dev/null
+++ b/src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XSLTSimpleContentConstructor_H
+#define Patternist_XSLTSimpleContentConstructor_H
+
+#include "qsimplecontentconstructor_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XSL-T's construction of simple content, which is
+ * different from XQuery's approach.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#constructing-simple-content">XSL
+ * Transformations (XSLT) Version 2.0, 5.7.2 Constructing Simple Content</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class XSLTSimpleContentConstructor : public SimpleContentConstructor
+ {
+ public:
+ XSLTSimpleContentConstructor(const Expression::Ptr &source);
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ private:
+ static inline QString processItem(const Item &item,
+ bool &discard,
+ bool &isText);
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
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..f6cdf04
--- /dev/null
+++ b/src/xmlpatterns/functions/qabstractfunctionfactory.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..a84bb4c
--- /dev/null
+++ b/src/xmlpatterns/functions/qabstractfunctionfactory_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..f789cd9
--- /dev/null
+++ b/src/xmlpatterns/functions/qaccessorfns.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..3275e3d
--- /dev/null
+++ b/src/xmlpatterns/functions/qaccessorfns_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..1eae34f
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregatefns.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..9d8606d
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregatefns_p.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..fc68d65
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregator.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..0dac0c6
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregator_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..076bd6a
--- /dev/null
+++ b/src/xmlpatterns/functions/qassemblestringfns.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..7fb9499
--- /dev/null
+++ b/src/xmlpatterns/functions/qassemblestringfns_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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..d90ca79
--- /dev/null
+++ b/src/xmlpatterns/functions/qbooleanfns.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..a32bc40
--- /dev/null
+++ b/src/xmlpatterns/functions/qbooleanfns_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..4a98c2f
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparescaseaware.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..a325671
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparescaseaware_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..79fa0ea
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparestringfns.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..ec97648
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparestringfns_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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..749e779
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparingaggregator.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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(QPatternist::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();
+
+ // explicit scope needed in RVCT
+ ComparingAggregator<oper, result>::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..9fc8457
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparingaggregator_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..a2986c7
--- /dev/null
+++ b/src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..4b10621
--- /dev/null
+++ b/src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..58e3176
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextfns.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..66d2775
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextfns_p.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..3a9117c
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextnodechecker.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..bc3e8b4
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextnodechecker_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..7e48e29
--- /dev/null
+++ b/src/xmlpatterns/functions/qcurrentfn.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..9916faa
--- /dev/null
+++ b/src/xmlpatterns/functions/qcurrentfn_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..c74f39d
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefn.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..64a46ee
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..5648482
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefns.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..cd5ca6f
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefns_p.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..f59b933
--- /dev/null
+++ b/src/xmlpatterns/functions/qdeepequalfn.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..d122d47
--- /dev/null
+++ b/src/xmlpatterns/functions/qdeepequalfn_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..5802efe
--- /dev/null
+++ b/src/xmlpatterns/functions/qdocumentfn.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..a3de8db
--- /dev/null
+++ b/src/xmlpatterns/functions/qdocumentfn_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..3a32503
--- /dev/null
+++ b/src/xmlpatterns/functions/qelementavailablefn.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..7e4b746
--- /dev/null
+++ b/src/xmlpatterns/functions/qelementavailablefn_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..60325f6
--- /dev/null
+++ b/src/xmlpatterns/functions/qerrorfn.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..857c6f8
--- /dev/null
+++ b/src/xmlpatterns/functions/qerrorfn_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..3bcc55d
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionargument.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..e87ccb6
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionargument_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..004513c
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionavailablefn.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..e295e61
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionavailablefn_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..3ea3edf
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctioncall.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..f077956
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctioncall_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..ba1a679
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactory.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..680bd4a
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactory_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..e089972
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactorycollection.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..afd6379
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactorycollection_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..a205da9
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionsignature.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..32014b9
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionsignature_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..9786740
--- /dev/null
+++ b/src/xmlpatterns/functions/qgenerateidfn.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..1f3dcd0
--- /dev/null
+++ b/src/xmlpatterns/functions/qgenerateidfn_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..e14fcbc
--- /dev/null
+++ b/src/xmlpatterns/functions/qnodefns.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..ba8de1e
--- /dev/null
+++ b/src/xmlpatterns/functions/qnodefns_p.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..af4530c
--- /dev/null
+++ b/src/xmlpatterns/functions/qnumericfns.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..0b0d1d3
--- /dev/null
+++ b/src/xmlpatterns/functions/qnumericfns_p.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..ca14d9b
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternmatchingfns.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.captureCount(), 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..3d792cd
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternmatchingfns_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..d0df69c
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternplatform.cpp
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 &pattern,
+ const ReportContext::Ptr &context) const
+{
+ return parsePattern(pattern, context, this);
+}
+
+QRegExp PatternPlatform::parsePattern(const QString &patternP,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const location)
+{
+ 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."),
+ ReportContext::FOER0000, location);
+ 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_\\-\\.]"));
+
+ QRegExp retval(rewrittenPattern, Qt::CaseSensitive, QRegExp::W3CXmlSchema11);
+
+ 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, location);
+ 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..99bf061
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternplatform_p.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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;
+
+ /**
+ * @short Parses pattern
+ */
+ static QRegExp parsePattern(const QString &pattern,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const location);
+
+
+ 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;
+
+ /**
+ * @short Calls the public parsePattern() function and passes in @c
+ * this as the location.
+ */
+ inline QRegExp parsePattern(const QString &pattern,
+ const ReportContext::Ptr &context) const;
+
+ Q_DISABLE_COPY(PatternPlatform)
+
+ Flags parseFlags(const QString &flags,
+ 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.captureCount();
+ 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..90031dc
--- /dev/null
+++ b/src/xmlpatterns/functions/qqnamefns.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..c1f1d45
--- /dev/null
+++ b/src/xmlpatterns/functions/qqnamefns_p.h
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..d01b91b
--- /dev/null
+++ b/src/xmlpatterns/functions/qresolveurifn.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..fec8652
--- /dev/null
+++ b/src/xmlpatterns/functions/qresolveurifn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..a234377
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencefns.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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;
+ 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..a755a0b
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencefns_p.h
@@ -0,0 +1,344 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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)
+ {
+ // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is
+ // passed directly into another constructor.
+ Q_ASSERT(Id == IDExistsFN || Id == IDEmptyFN);
+
+ const Expression::Ptr me(FunctionCall::compress(context));
+
+ if(me != this)
+ return me;
+
+ // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is
+ // passed directly into another constructor.
+ Expression::ID tempId = Id;
+ const Cardinality myCard((tempId == 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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..1dced45
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 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 <frans.englich@nokia.com>
+ */
+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..6d3e2e4
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencegeneratingfns_p.h
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..1bd5d7a
--- /dev/null
+++ b/src/xmlpatterns/functions/qstaticbaseuricontainer_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..9cd6847
--- /dev/null
+++ b/src/xmlpatterns/functions/qstaticnamespacescontainer.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..9e87e74
--- /dev/null
+++ b/src/xmlpatterns/functions/qstaticnamespacescontainer_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..8752c7a
--- /dev/null
+++ b/src/xmlpatterns/functions/qstringvaluefns.cpp
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..c88d52a
--- /dev/null
+++ b/src/xmlpatterns/functions/qstringvaluefns_p.h
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..8dc55f0
--- /dev/null
+++ b/src/xmlpatterns/functions/qsubstringfns.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..f41039b
--- /dev/null
+++ b/src/xmlpatterns/functions/qsubstringfns_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..14870c5
--- /dev/null
+++ b/src/xmlpatterns/functions/qsystempropertyfn.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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://qt.nokia.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..c3b63fe
--- /dev/null
+++ b/src/xmlpatterns/functions/qsystempropertyfn_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..411b894
--- /dev/null
+++ b/src/xmlpatterns/functions/qtimezonefns.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..3032603
--- /dev/null
+++ b/src/xmlpatterns/functions/qtimezonefns_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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 <frans.englich@nokia.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..e64612d
--- /dev/null
+++ b/src/xmlpatterns/functions/qtracefn.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..cfe49dd
--- /dev/null
+++ b/src/xmlpatterns/functions/qtracefn_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..d84c0eb
--- /dev/null
+++ b/src/xmlpatterns/functions/qtypeavailablefn.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..cdbe05b
--- /dev/null
+++ b/src/xmlpatterns/functions/qtypeavailablefn_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..564d9c8
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..b8348cc
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..3c511ac
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentityurifn.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..4d8ee5b
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentityurifn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..085ff4a
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextavailablefn.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..088edd1
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextavailablefn_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..2750413
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextfn.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..80f3fdd
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextfn_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..6441bd0
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath10corefunctions.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..c50c709
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath10corefunctions_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..cc21dfb
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath20corefunctions.cpp
@@ -0,0 +1,748 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..47abd4e
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath20corefunctions_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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..86c73e9
--- /dev/null
+++ b/src/xmlpatterns/functions/qxslt20corefunctions.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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..df044b4
--- /dev/null
+++ b/src/xmlpatterns/functions/qxslt20corefunctions_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 <frans.englich@nokia.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
diff --git a/src/xmlpatterns/iterators/iterators.pri b/src/xmlpatterns/iterators/iterators.pri
new file mode 100644
index 0000000..3850334
--- /dev/null
+++ b/src/xmlpatterns/iterators/iterators.pri
@@ -0,0 +1,29 @@
+HEADERS += $$PWD/qcachingiterator_p.h \
+ $$PWD/qdeduplicateiterator_p.h \
+ $$PWD/qdistinctiterator_p.h \
+ $$PWD/qemptyiterator_p.h \
+ $$PWD/qexceptiterator_p.h \
+ $$PWD/qindexofiterator_p.h \
+ $$PWD/qinsertioniterator_p.h \
+ $$PWD/qintersectiterator_p.h \
+ $$PWD/qitemmappingiterator_p.h \
+ $$PWD/qrangeiterator_p.h \
+ $$PWD/qremovaliterator_p.h \
+ $$PWD/qsequencemappingiterator_p.h \
+ $$PWD/qsingletoniterator_p.h \
+ $$PWD/qsubsequenceiterator_p.h \
+ $$PWD/qtocodepointsiterator_p.h \
+ $$PWD/qunioniterator_p.h
+
+SOURCES += $$PWD/qcachingiterator.cpp \
+ $$PWD/qdeduplicateiterator.cpp \
+ $$PWD/qdistinctiterator.cpp \
+ $$PWD/qexceptiterator.cpp \
+ $$PWD/qindexofiterator.cpp \
+ $$PWD/qinsertioniterator.cpp \
+ $$PWD/qintersectiterator.cpp \
+ $$PWD/qrangeiterator.cpp \
+ $$PWD/qremovaliterator.cpp \
+ $$PWD/qsubsequenceiterator.cpp \
+ $$PWD/qtocodepointsiterator.cpp \
+ $$PWD/qunioniterator.cpp
diff --git a/src/xmlpatterns/iterators/qcachingiterator.cpp b/src/xmlpatterns/iterators/qcachingiterator.cpp
new file mode 100644
index 0000000..1c0487d
--- /dev/null
+++ b/src/xmlpatterns/iterators/qcachingiterator.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+#include "qcachingiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CachingIterator::CachingIterator(ItemSequenceCacheCell::Vector &cacheCells,
+ const VariableSlotID slot,
+ const DynamicContext::Ptr &context) : m_position(0),
+ m_varSlot(slot),
+ m_context(context),
+ m_cacheCells(cacheCells),
+ m_usingCache(true)
+{
+ Q_ASSERT(m_varSlot > -1);
+ Q_ASSERT(m_context);
+ Q_ASSERT(m_cacheCells.at(m_varSlot).sourceIterator);
+ Q_ASSERT_X((m_cacheCells.at(m_varSlot).cachedItems.isEmpty() && m_cacheCells.at(m_varSlot).cacheState == ItemSequenceCacheCell::Empty) ||
+ m_cacheCells.at(m_varSlot).cacheState == ItemSequenceCacheCell::PartiallyPopulated,
+ Q_FUNC_INFO,
+ "It makes no sense to construct a CachingIterator for a cache that is ItemSequenceCacheCell::Full.");
+}
+
+Item CachingIterator::next()
+{
+ ItemSequenceCacheCell &cell = m_cacheCells[m_varSlot];
+ if(m_position == -1)
+ return Item();
+
+ if(m_usingCache)
+ {
+ ++m_position;
+
+ /* QAbstractXmlForwardIterator::position() starts at 1, while Qt's container classes
+ * starts at 0. */
+ if(m_position - 1 < cell.cachedItems.count())
+ {
+ m_current = cell.cachedItems.at(m_position - 1);
+ return m_current;
+ }
+ else
+ {
+ cell.cacheState = ItemSequenceCacheCell::PartiallyPopulated;
+ m_usingCache = false;
+ /* We decrement here so we don't have to add a branch for this
+ * when using the source QAbstractXmlForwardIterator below. */
+ --m_position;
+ }
+ }
+
+ m_current = cell.sourceIterator->next();
+
+ if(m_current)
+ {
+ cell.cachedItems.append(m_current);
+ Q_ASSERT(cell.cacheState == ItemSequenceCacheCell::PartiallyPopulated);
+ ++m_position;
+ return m_current;
+ }
+ else
+ {
+ m_position = -1;
+ cell.cacheState = ItemSequenceCacheCell::Full;
+ return Item();
+ }
+}
+
+Item CachingIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger CachingIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr CachingIterator::copy() const
+{
+ const ItemSequenceCacheCell &cell = m_cacheCells.at(m_varSlot);
+ if(cell.cacheState == ItemSequenceCacheCell::Full)
+ return makeListIterator(cell.cachedItems);
+ else
+ return Item::Iterator::Ptr(new CachingIterator(m_cacheCells, m_varSlot, m_context));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qcachingiterator_p.h b/src/xmlpatterns/iterators/qcachingiterator_p.h
new file mode 100644
index 0000000..b9debb9
--- /dev/null
+++ b/src/xmlpatterns/iterators/qcachingiterator_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CachingIterator_H
+#define Patternist_CachingIterator_H
+
+#include <QList>
+#include <QVector>
+
+#include "qdynamiccontext_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short An QAbstractXmlForwardIterator that gets its item from a cache unless its empty, in
+ * which case it continues to populate the cache as well as deliver on its
+ * own from a source QAbstractXmlForwardIterator.
+ *
+ * @author Frans Englich <frans.frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class CachingIterator : public Item::Iterator
+ {
+ public:
+ /**
+ * We always use the same cache cell so why don't we use it directly,
+ * instead of passing the slot and ItemSequenceCacheCell::Vector to
+ * this class? Because the GenericDynamicContext might decide to resize
+ * the vector and that would invalidate the reference.
+ *
+ * We intentionally pass in a non-const reference here.
+ */
+ CachingIterator(ItemSequenceCacheCell::Vector &cacheCells,
+ const VariableSlotID slot,
+ const DynamicContext::Ptr &context);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ Item m_current;
+ xsInteger m_position;
+
+ /**
+ * This variable cannot be called m_slot, because
+ * /usr/include/sys/sysmacros.h on hpuxi-acc defines it.
+ */
+ const VariableSlotID m_varSlot;
+
+ /**
+ * We don't use the context. We only keep a reference such that it
+ * doesn't get deleted, and m_cacheCells starts to dangle.
+ */
+ const DynamicContext::Ptr m_context;
+
+ /**
+ * We intentionally store a reference here such that we are able to
+ * modify the item.
+ */
+ ItemSequenceCacheCell::Vector &m_cacheCells;
+
+ /**
+ * Whether this CachingIterator is delivering items from
+ * m_cacheCell.cacheItems or from m_cacheCell.sourceIterator.
+ */
+ bool m_usingCache;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qdeduplicateiterator.cpp b/src/xmlpatterns/iterators/qdeduplicateiterator.cpp
new file mode 100644
index 0000000..546eae4
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdeduplicateiterator.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeduplicateiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DeduplicateIterator::DeduplicateIterator(const Item::List &source) : ListIterator<Item>(source)
+ , m_listPos(0)
+{
+ Q_ASSERT(!Item());
+ Q_ASSERT(!Item().isNode());
+ Q_ASSERT(!Item().isAtomicValue());
+}
+
+Item DeduplicateIterator::next()
+{
+ if(m_listPos == m_list.count())
+ {
+ m_current.reset();
+ m_position = -1;
+ return Item();
+ }
+
+ Item next(m_list.at(m_listPos));
+
+ while(next.asNode().is(m_current.asNode()))
+ {
+ ++m_listPos;
+ if(m_listPos == m_list.count())
+ {
+ m_current.reset();
+ m_position = -1;
+ return Item();
+ }
+ else
+ next = m_list.at(m_listPos);
+ }
+
+ ++m_position;
+ m_current = next;
+ return next;
+}
+
+xsInteger DeduplicateIterator::count()
+{
+ return QAbstractXmlForwardIterator<Item>::count();
+}
+
+Item::Iterator::Ptr DeduplicateIterator::copy() const
+{
+ return Item::Iterator::Ptr(new DeduplicateIterator(m_list));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qdeduplicateiterator_p.h b/src/xmlpatterns/iterators/qdeduplicateiterator_p.h
new file mode 100644
index 0000000..b3f92e1
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdeduplicateiterator_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DeduplicateIterator_H
+#define Patternist_DeduplicateIterator_H
+
+#include <QList>
+
+#include "qexpression_p.h"
+#include "qitem_p.h"
+#include "qatomiccomparator_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qsourcelocationreflection_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Performs deduplication of the nodes on its source list.
+ *
+ * @note The nodes in the source list must be in document order.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class DeduplicateIterator : public ListIterator<Item>
+ {
+ public:
+ DeduplicateIterator(const Item::List &source);
+
+ virtual Item next();
+ virtual Item::Iterator::Ptr copy() const;
+ virtual xsInteger count();
+
+ private:
+ /**
+ * m_position in ListIteratorPlatform is the position that we
+ * show to the outside through position) but do not correspond
+ * to the position in m_list, since we skip entries in that one.
+ *
+ * However, this guy, m_listPos, is the position into m_list.
+ */
+ int m_listPos;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qdistinctiterator.cpp b/src/xmlpatterns/iterators/qdistinctiterator.cpp
new file mode 100644
index 0000000..cf04de7
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdistinctiterator.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qdistinctiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DistinctIterator::DistinctIterator(const Item::Iterator::Ptr &seq,
+ const AtomicComparator::Ptr &comp,
+ const Expression::ConstPtr &expression,
+ const DynamicContext::Ptr &context)
+ : m_seq(seq)
+ , m_context(context)
+ , m_expr(expression)
+ , m_position(0)
+{
+ Q_ASSERT(seq);
+ prepareComparison(comp);
+}
+
+Item DistinctIterator::next()
+{
+ if(m_position == -1)
+ return Item();
+
+ const Item nitem(m_seq->next());
+ if(!nitem)
+ {
+ m_position = -1;
+ m_current.reset();
+ return Item();
+ }
+
+ const Item::List::const_iterator end(m_processed.constEnd());
+ Item::List::const_iterator it(m_processed.constBegin());
+
+ for(; it != end; ++it)
+ {
+ if(flexibleCompare(*it, nitem, m_context))
+ {
+ return next();
+ }
+ }
+
+ m_current = nitem;
+ ++m_position;
+ m_processed.append(nitem);
+ return nitem;
+}
+
+Item DistinctIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger DistinctIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr DistinctIterator::copy() const
+{
+ return Item::Iterator::Ptr(new DistinctIterator(m_seq->copy(), comparator(), m_expr, m_context));
+}
+
+const SourceLocationReflection *DistinctIterator::actualReflection() const
+{
+ return m_expr.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qdistinctiterator_p.h b/src/xmlpatterns/iterators/qdistinctiterator_p.h
new file mode 100644
index 0000000..70d7e3a
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdistinctiterator_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DistinctIterator_H
+#define Patternist_DistinctIterator_H
+
+#include <QList>
+
+#include "qexpression_p.h"
+#include "qitem_p.h"
+#include "qatomiccomparator_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qsourcelocationreflection_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Filters another sequence by removing duplicates such that the items are unique.
+ *
+ * DistinctIterator takes an input sequence, and returns a sequence where each
+ * item is unique. Thus, DistinctIterator removes the duplicates of items
+ * in a sequence. DistinctIterator is central in the implementation of the
+ * <tt>fn:distinct-values()</tt> function.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-distinct-values">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.1.6 fn:distinct-values</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class DistinctIterator : public Item::Iterator
+ , public ComparisonPlatform<DistinctIterator, false>
+ , public SourceLocationReflection
+ {
+ public:
+ /**
+ * Creates a DistinctIterator.
+ * @param comp the AtomicComparator to be used for comparing values. This may be @c null,
+ * meaning the IndexOfIterator iterator will dynamically determine what comparator to use
+ * @param seq the sequence whose duplicates should be filtered out
+ * @param context the usual context, used for error reporting and by AtomicComparators.
+ * @param expression the Expression that this DistinctIterator is
+ * evaluating for. It is used for error reporting, via
+ * actualReflection().
+ */
+ DistinctIterator(const Item::Iterator::Ptr &seq,
+ const AtomicComparator::Ptr &comp,
+ const Expression::ConstPtr &expression,
+ const DynamicContext::Ptr &context);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual Item::Iterator::Ptr copy() const;
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return AtomicComparator::OperatorEqual;
+ }
+
+ private:
+ const Item::Iterator::Ptr m_seq;
+ const DynamicContext::Ptr m_context;
+ const Expression::ConstPtr m_expr;
+ Item m_current;
+ xsInteger m_position;
+ Item::List m_processed;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qemptyiterator_p.h b/src/xmlpatterns/iterators/qemptyiterator_p.h
new file mode 100644
index 0000000..b0feb1a
--- /dev/null
+++ b/src/xmlpatterns/iterators/qemptyiterator_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_EmptyIterator_H
+#define Patternist_EmptyIterator_H
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qprimitives_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short An QAbstractXmlForwardIterator which always is empty.
+ *
+ * EmptyIterator is an QAbstractXmlForwardIterator over the type @c T, which always is empty. Other
+ * iterators can also be empty(or, at least behave as they are empty), but this
+ * class is special designed for this purpose and is therefore fast.
+ *
+ * EmptyIterator's constructor is protected, instances is retrieved from CommonValues.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ template<typename T> class EmptyIterator : public QAbstractXmlForwardIterator<T>
+ {
+ public:
+ /**
+ * @returns always a default constructed value, T().
+ */
+ virtual T next()
+ {
+ return T();
+ }
+
+ /**
+ * @returns always a default constructed value, T().
+ */
+ virtual T current() const
+ {
+ return T();
+ }
+
+ /**
+ * @returns always 0.
+ */
+ virtual xsInteger position() const
+ {
+ return 0;
+ }
+
+ /**
+ * @returns always @c this, the reverse of <tt>()</tt> is <tt>()</tt>.
+ */
+ virtual typename QAbstractXmlForwardIterator<T>::Ptr toReversed()
+ {
+ return typename QAbstractXmlForwardIterator<T>::Ptr(const_cast<EmptyIterator<T> *>(this));
+ }
+
+ /**
+ * @returns always 0
+ */
+ virtual xsInteger count()
+ {
+ return 0;
+ }
+
+ /**
+ * @returns @c this
+ */
+ virtual typename QAbstractXmlForwardIterator<T>::Ptr copy() const
+ {
+ return typename QAbstractXmlForwardIterator<T>::Ptr(const_cast<EmptyIterator *>(this));
+ }
+
+ protected:
+ friend class CommonValues;
+ };
+
+ template<typename T>
+ static inline
+ typename QAbstractXmlForwardIterator<T>::Ptr
+ makeEmptyIterator()
+ {
+ return typename QAbstractXmlForwardIterator<T>::Ptr(new EmptyIterator<T>());
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qexceptiterator.cpp b/src/xmlpatterns/iterators/qexceptiterator.cpp
new file mode 100644
index 0000000..9540167
--- /dev/null
+++ b/src/xmlpatterns/iterators/qexceptiterator.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+
+#include "qexceptiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExceptIterator::ExceptIterator(const Item::Iterator::Ptr &it1,
+ const Item::Iterator::Ptr &it2) : m_it1(it1)
+ , m_it2(it2)
+ , m_position(0)
+ , m_node1(m_it1->next())
+ , m_node2(m_it2->next())
+{
+ Q_ASSERT(m_it1);
+ Q_ASSERT(m_it2);
+}
+
+Item ExceptIterator::fromFirstOperand()
+{
+ ++m_position;
+ m_current = m_node1;
+ m_node1 = m_it1->next();
+
+ return m_current;
+}
+
+Item ExceptIterator::next()
+{
+ while(true)
+ {
+ if(!m_node1)
+ {
+ m_position = -1;
+ m_current = Item();
+ return Item();
+ }
+ else if(!m_node2)
+ return fromFirstOperand();
+
+ if(m_node1.asNode().model() != m_node2.asNode().model())
+ return fromFirstOperand();
+
+ switch(m_node1.asNode().compareOrder(m_node2.asNode()))
+ {
+ case QXmlNodeModelIndex::Precedes:
+ return fromFirstOperand();
+ case QXmlNodeModelIndex::Follows:
+ {
+ m_node2 = m_it2->next();
+ if(m_node2)
+ continue;
+ else
+ return fromFirstOperand();
+ }
+ default:
+ {
+ m_node1 = m_it1->next();
+ m_node2 = m_it2->next();
+ }
+ }
+ }
+}
+
+Item ExceptIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger ExceptIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr ExceptIterator::copy() const
+{
+ return Item::Iterator::Ptr(new ExceptIterator(m_it1->copy(), m_it2->copy()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qexceptiterator_p.h b/src/xmlpatterns/iterators/qexceptiterator_p.h
new file mode 100644
index 0000000..a66a74a
--- /dev/null
+++ b/src/xmlpatterns/iterators/qexceptiterator_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ExceptIterator_H
+#define Patternist_ExceptIterator_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the @c except operator. That is, the computation
+ * of the sequence of nodes from one sequence, that doesn't appear in the
+ * other.
+ *
+ * @ingroup Patternist_iterators
+ */
+ class ExceptIterator : public Item::Iterator
+ {
+ public:
+ /**
+ * It is assumed that @p it1 and @p it2 are in document order and
+ * without duplicates.
+ */
+ ExceptIterator(const Item::Iterator::Ptr &it1,
+ const Item::Iterator::Ptr &it2);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ inline Item fromFirstOperand();
+
+ const Item::Iterator::Ptr m_it1;
+ const Item::Iterator::Ptr m_it2;
+ Item m_current;
+ xsInteger m_position;
+ Item m_node1;
+ Item m_node2;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qindexofiterator.cpp b/src/xmlpatterns/iterators/qindexofiterator.cpp
new file mode 100644
index 0000000..dc7f8b7
--- /dev/null
+++ b/src/xmlpatterns/iterators/qindexofiterator.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qinteger_p.h"
+
+#include "qindexofiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+IndexOfIterator::IndexOfIterator(const Item::Iterator::Ptr &seq,
+ const Item &searchParam,
+ const AtomicComparator::Ptr &comp,
+ const DynamicContext::Ptr &context,
+ const Expression::ConstPtr &expr)
+ : m_seq(seq)
+ , m_searchParam(searchParam)
+ , m_context(context)
+ , m_expr(expr)
+ , m_position(0)
+ , m_seqPos(0)
+{
+ Q_ASSERT(seq);
+ Q_ASSERT(searchParam);
+ prepareComparison(comp);
+}
+
+Item IndexOfIterator::next()
+{
+ if(m_position == -1)
+ return Item();
+
+ const Item item(m_seq->next());
+ ++m_seqPos;
+
+ if(!item)
+ {
+ m_current.reset();
+ m_position = -1;
+ return Item();
+ }
+
+ if(flexibleCompare(item, m_searchParam, m_context))
+ {
+ ++m_position;
+ return Integer::fromValue(m_seqPos);
+ }
+
+ return next();
+}
+
+Item IndexOfIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger IndexOfIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr IndexOfIterator::copy() const
+{
+ return Item::Iterator::Ptr(new IndexOfIterator(m_seq->copy(),
+ m_searchParam,
+ comparator(),
+ m_context,
+ m_expr));
+}
+
+const SourceLocationReflection *IndexOfIterator::actualReflection() const
+{
+ return m_expr.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qindexofiterator_p.h b/src/xmlpatterns/iterators/qindexofiterator_p.h
new file mode 100644
index 0000000..cd1eaf6
--- /dev/null
+++ b/src/xmlpatterns/iterators/qindexofiterator_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_IndexOfIterator_H
+#define Patternist_IndexOfIterator_H
+
+#include "qitem_p.h"
+#include "qatomiccomparator_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qdynamiccontext_p.h"
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Forms an QAbstractXmlForwardIterator over a sequence of integers, which each is the position
+ * of where a search parameter appeared in another QAbstractXmlForwardIterator.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-index-of">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.1.3 fn:index-of</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class IndexOfIterator : public Item::Iterator
+ , public ComparisonPlatform<IndexOfIterator, false>
+ , public SourceLocationReflection
+ {
+ public:
+
+ /**
+ * Creates an IndexOfIterator, whose next() function returns integers being
+ * the index positions of where @p searchParam was found in @p inputSequence.
+ *
+ * @param comp the AtomicComparator to be used for comparing values. This may be @c null,
+ * meaning the IndexOfIterator iterator will dynamically determine what comparator to use
+ * on an item per item basis, which is slower.
+ * @param searchParam the item which should be compared to the items in @p inputSequence.
+ * @param inputSequence the input sequence which indexes of the @p searchParam should
+ * be returned for.
+ * @param context the usual DynamicContext
+ * @param expr the Expression that this IndexOfIterator is evaluating
+ * for. It is used for error reporting, via actualReflection().
+ */
+ IndexOfIterator(const Item::Iterator::Ptr &inputSequence,
+ const Item &searchParam,
+ const AtomicComparator::Ptr &comp,
+ const DynamicContext::Ptr &context,
+ const Expression::ConstPtr &expr);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual Item::Iterator::Ptr copy() const;
+
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return AtomicComparator::OperatorEqual;
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ const Item::Iterator::Ptr m_seq;
+ const Item m_searchParam;
+ const DynamicContext::Ptr m_context;
+ const Expression::ConstPtr m_expr;
+ Item m_current;
+ xsInteger m_position;
+ xsInteger m_seqPos;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qinsertioniterator.cpp b/src/xmlpatterns/iterators/qinsertioniterator.cpp
new file mode 100644
index 0000000..c1bd384
--- /dev/null
+++ b/src/xmlpatterns/iterators/qinsertioniterator.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qinsertioniterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+InsertionIterator::InsertionIterator(const Item::Iterator::Ptr &target,
+ const xsInteger pos,
+ const Item::Iterator::Ptr &inserts)
+ : m_target(target),
+ m_insertPos(pos),
+ m_inserts(inserts),
+ m_position(0),
+ m_isInserting(pos == 1)
+{
+ Q_ASSERT(target);
+ Q_ASSERT(inserts);
+ Q_ASSERT(m_insertPos >= 1);
+}
+
+Item InsertionIterator::next()
+{
+ if(m_isInserting)
+ {
+ m_current = m_inserts->next();
+
+ if(m_current)
+ {
+ ++m_position;
+ return m_current;
+ }
+ }
+ else if(m_position == (m_insertPos - 1) && !m_isInserting)
+ { /* Entered only the first time insertion starts. */
+ m_isInserting = true;
+ return next();
+ }
+
+ ++m_position;
+ m_current = m_target->next();
+
+ if(m_current)
+ return m_current;
+ else if(m_inserts->position() == -1) /* We're at the end of the both iterators. */
+ {
+ m_position = -1;
+ m_current.reset();
+ return Item();
+ }
+
+ /* Insert the insertion iterator, since it's still left. */
+ Q_ASSERT(m_target->position() < m_insertPos);
+ m_isInserting = true;
+ m_current = m_inserts->next();
+
+ if(m_current)
+ return m_current;
+ else
+ {
+ /* m_current is already null, so no need to reset it. */
+ m_position = -1;
+ return Item();
+ }
+}
+
+xsInteger InsertionIterator::count()
+{
+ return m_target->count() + m_inserts->count();
+}
+
+Item InsertionIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger InsertionIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr InsertionIterator::copy() const
+{
+ return Item::Iterator::Ptr(new InsertionIterator(m_target->copy(), m_insertPos, m_inserts->copy()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qinsertioniterator_p.h b/src/xmlpatterns/iterators/qinsertioniterator_p.h
new file mode 100644
index 0000000..dac8d82
--- /dev/null
+++ b/src/xmlpatterns/iterators/qinsertioniterator_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_InsertionIterator_H
+#define Patternist_InsertionIterator_H
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Conceptually inserts one QAbstractXmlForwardIterator into another, make two QAbstractXmlForwardIterator instances appear as one.
+ *
+ * An InsertionIterator represents a sequence that is the merge of two
+ * sequences, where one of the iterators is conceptually inserted at a
+ * given position. This is done while retaining the characteristic of being
+ * pull-based.
+ *
+ * InsertionIterator contains the logic for the implementation of the <tt>fn:insert-before()</tt>
+ * function, whose definition therefore specifies the detailed behaviors of the
+ * InsertionIterator.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-insert-before">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.1.7 fn:insert-before</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class InsertionIterator : public Item::Iterator
+ {
+ public:
+
+ /**
+ * Creates an InsertionIterator whose result is a merge of the
+ * iterator @p insertIterator into the iterator @p target at position @p
+ * position.
+ *
+ * @param target the iterator containing the items that the
+ * item in @p insertIterator will be inserted into.
+ * @param position the insertion position. Must be 1 or larger
+ * @param insertIterator the iterator containing the items to insert
+ * at position @p position
+ */
+ InsertionIterator(const Item::Iterator::Ptr &target,
+ const xsInteger position,
+ const Item::Iterator::Ptr &insertIterator);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual xsInteger count();
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ const Item::Iterator::Ptr m_target;
+ const xsInteger m_insertPos;
+ const Item::Iterator::Ptr m_inserts;
+ Item m_current;
+ xsInteger m_position;
+ bool m_isInserting;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qintersectiterator.cpp b/src/xmlpatterns/iterators/qintersectiterator.cpp
new file mode 100644
index 0000000..579ce92
--- /dev/null
+++ b/src/xmlpatterns/iterators/qintersectiterator.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+
+#include "qintersectiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+IntersectIterator::IntersectIterator(const Item::Iterator::Ptr &it1,
+ const Item::Iterator::Ptr &it2) : m_it1(it1),
+ m_it2(it2),
+ m_position(0),
+ m_node1(m_it1->next()),
+ m_node2(m_it2->next())
+{
+ Q_ASSERT(m_it1);
+ Q_ASSERT(m_it2);
+}
+
+Item IntersectIterator::next()
+{
+ if(!m_node1 || !m_node2)
+ return closedExit();
+
+ do
+ {
+ if(m_node1.asNode().model() == m_node2.asNode().model())
+ {
+ switch(m_node1.asNode().compareOrder(m_node2.asNode()))
+ {
+ case QXmlNodeModelIndex::Precedes:
+ {
+ m_node1 = m_it1->next();
+ break;
+ }
+ case QXmlNodeModelIndex::Follows:
+ {
+ m_node2 = m_it2->next();
+ break;
+ }
+ default:
+ {
+ m_current = m_node2;
+ m_node1 = m_it1->next();
+ m_node2 = m_it2->next();
+ ++m_position;
+ return m_current;
+ }
+ }
+ }
+ else
+ m_node2 = m_it2->next();
+ }
+ while(m_node1 && m_node2);
+
+ return Item();
+}
+
+Item IntersectIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger IntersectIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr IntersectIterator::copy() const
+{
+ return Item::Iterator::Ptr(new IntersectIterator(m_it1->copy(), m_it2->copy()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qintersectiterator_p.h b/src/xmlpatterns/iterators/qintersectiterator_p.h
new file mode 100644
index 0000000..0cba64c
--- /dev/null
+++ b/src/xmlpatterns/iterators/qintersectiterator_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_IntersectIterator_H
+#define Patternist_IntersectIterator_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the @c intersect operator. That is, the computation
+ * of the intersection between two sequences of nodes.
+ *
+ * The @c intersect operator can be seen as logical @c AND of the two sets.
+ *
+ * @ingroup Patternist_iterators
+ */
+ class IntersectIterator : public Item::Iterator
+ {
+ public:
+ /**
+ * It is assumed that @p it1 and @p it2 are in document order and
+ * without duplicates.
+ */
+ IntersectIterator(const Item::Iterator::Ptr &it1,
+ const Item::Iterator::Ptr &it2);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ inline Item closedExit()
+ {
+ m_position = -1;
+ m_current = Item();
+ return Item();
+ }
+
+ const Item::Iterator::Ptr m_it1;
+ const Item::Iterator::Ptr m_it2;
+ Item m_current;
+ xsInteger m_position;
+ Item m_node1;
+ Item m_node2;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qitemmappingiterator_p.h b/src/xmlpatterns/iterators/qitemmappingiterator_p.h
new file mode 100644
index 0000000..2aada7b
--- /dev/null
+++ b/src/xmlpatterns/iterators/qitemmappingiterator_p.h
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ItemMappingIterator_H
+#define Patternist_ItemMappingIterator_H
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qdynamiccontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Proxies another QAbstractXmlForwardIterator, and for each item, returns the
+ * Item returned from a mapping function.
+ *
+ * ItemMappingIterator is practical when the items in an QAbstractXmlForwardIterator needs to
+ * be translated to another sequence, while still doing it in a pipe-lined
+ * fashion.
+ *
+ * This is achieved by that ItemMappingIterator's constructor takes
+ * an instance of a class, that must have the following member:
+ *
+ * @code
+ * TResult::Ptr mapToItem(const TSource &item,
+ * const Context &context) const
+ * @endcode
+ *
+ * For each item in the QAbstractXmlForwardIterator ItemMappingIterator proxies, this function is
+ * called and its return value becomes the return value of the ItemMappingIterator. If the
+ * mapping function returns null, ItemMappingIterator maps the next item in the source sequence
+ * such that a contiguous sequence of items is returned.
+ *
+ * Declaring the mapToItem() function as inline, can be a good way to improve performance.
+ *
+ * @see SequenceMappingIterator
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ template<typename TResult, typename TSource, typename TMapper, typename Context = DynamicContext::Ptr>
+ class ItemMappingIterator : public QAbstractXmlForwardIterator<TResult>
+ {
+ public:
+ /**
+ * Constructs an ItemMappingIterator.
+ *
+ * @param mapper the object that has the mapToItem() sequence.
+ * @param iterator the QAbstractXmlForwardIterator whose items should be mapped.
+ * @param context the context that will be passed to the map function.
+ * May be null.
+ */
+ ItemMappingIterator(const TMapper &mapper,
+ const typename QAbstractXmlForwardIterator<TSource>::Ptr &iterator,
+ const Context &context) : m_mapper(mapper)
+ , m_it(iterator)
+ , m_context(context)
+ , m_position(0)
+ {
+ Q_ASSERT(mapper);
+ Q_ASSERT(iterator);
+ }
+
+ /**
+ * @returns the next item in the sequence, or
+ * @c null if the end have been reached.
+ */
+ virtual TResult next()
+ {
+ const TSource sourceItem(m_it->next());
+
+ if(qIsForwardIteratorEnd(sourceItem))
+ {
+ m_current = TResult();
+ m_position = -1;
+ return TResult();
+ }
+ else
+ {
+ m_current = m_mapper->mapToItem(sourceItem, m_context);
+ if(qIsForwardIteratorEnd(m_current))
+ return next(); /* The mapper returned null, so continue with the next in the source. */
+ else
+ {
+ ++m_position;
+ return m_current;
+ }
+ }
+ }
+
+ virtual TResult current() const
+ {
+ return m_current;
+ }
+
+ virtual xsInteger position() const
+ {
+ return m_position;
+ }
+
+ virtual typename QAbstractXmlForwardIterator<TResult>::Ptr copy() const
+ {
+ return typename QAbstractXmlForwardIterator<TResult>::Ptr
+ (new ItemMappingIterator<TResult, TSource, TMapper, Context>(m_mapper, m_it->copy(), m_context));
+ }
+
+ private:
+ const TMapper m_mapper;
+ const typename QAbstractXmlForwardIterator<TSource>::Ptr m_it;
+ const Context m_context;
+ TResult m_current;
+ xsInteger m_position;
+ };
+
+ /**
+ * @short An object generator for ItemMappingIterator.
+ *
+ * makeItemMappingIterator() is a convenience function for avoiding specifying
+ * the full template instantiation for ItemMappingIterator. Conceptually, it
+ * is identical to Qt's qMakePair().
+ *
+ * @relates ItemMappingIterator
+ */
+ template<typename TResult, typename TSource, typename TMapper, typename Context>
+ static inline
+ typename QAbstractXmlForwardIterator<TResult>::Ptr
+ makeItemMappingIterator(const TMapper &mapper,
+ const QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<TSource> > &source,
+ const Context &context)
+ {
+ return typename QAbstractXmlForwardIterator<TResult>::Ptr
+ (new ItemMappingIterator<TResult, TSource, TMapper, Context>(mapper, source, context));
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qrangeiterator.cpp b/src/xmlpatterns/iterators/qrangeiterator.cpp
new file mode 100644
index 0000000..a37dff0
--- /dev/null
+++ b/src/xmlpatterns/iterators/qrangeiterator.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qinteger_p.h"
+
+#include "qrangeiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+RangeIterator::RangeIterator(const xsInteger start,
+ const Direction direction,
+ const xsInteger end)
+ : m_start(start),
+ m_end(end),
+ m_position(0),
+ m_count(start),
+ m_direction(direction),
+ m_increment(m_direction == Forward ? 1 : -1)
+{
+ Q_ASSERT(m_start < m_end);
+ Q_ASSERT(m_direction == Backward || m_direction == Forward);
+
+ if(m_direction == Backward)
+ {
+ qSwap(m_start, m_end);
+ m_count = m_start;
+ }
+}
+
+Item RangeIterator::next()
+{
+ if(m_position == -1)
+ return Item();
+ else if((m_direction == Forward && m_count > m_end) ||
+ (m_direction == Backward && m_count < m_end))
+ {
+ m_position = -1;
+ m_current.reset();
+ return Item();
+ }
+ else
+ {
+ m_current = Integer::fromValue(m_count);
+ m_count += m_increment;
+ ++m_position;
+ return m_current;
+ }
+}
+
+xsInteger RangeIterator::count()
+{
+ /* This complication is for handling that m_start & m_end may be reversed. */
+ xsInteger ret;
+
+ if(m_start < m_end)
+ ret = m_end - m_start;
+ else
+ ret = m_start - m_end;
+
+ return ret + 1;
+}
+
+Item::Iterator::Ptr RangeIterator::toReversed()
+{
+ return Item::Iterator::Ptr(new RangeIterator(m_start, Backward, m_end));
+}
+
+Item RangeIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger RangeIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr RangeIterator::copy() const
+{
+ if(m_direction == Backward)
+ return Item::Iterator::Ptr(new RangeIterator(m_end, Backward, m_start));
+ else
+ return Item::Iterator::Ptr(new RangeIterator(m_start, Forward, m_end));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qrangeiterator_p.h b/src/xmlpatterns/iterators/qrangeiterator_p.h
new file mode 100644
index 0000000..97829fd
--- /dev/null
+++ b/src/xmlpatterns/iterators/qrangeiterator_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_RangeIterator_H
+#define Patternist_RangeIterator_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short RangeIterator represents a sequence of integers between a
+ * start and end value.
+ *
+ * The RangeIterator contains the evaluation logic for the range expression, <tt>N to M</tt>,
+ * and its behavior is therefore consistent with the definition of that XPath expression.
+ * Hence, the detailed behavior of the RangeIterator can be found in the XPath 2.0
+ * specification.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/\#doc-xpath-RangeExpr">XML Path Language
+ * (XPath) 2.0, 3.3 Sequence Expressions, RangeExpr</a>
+ * @see RangeExpression
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ * @todo Documentation is missing
+ */
+ class Q_AUTOTEST_EXPORT RangeIterator : public Item::Iterator
+ {
+ public:
+
+ /**
+ * RangeIterator can iterate in both directions.
+ * This enumerator exist for identifying different directions.
+ */
+ enum Direction
+ {
+ /**
+ * Signifies that the QAbstractXmlForwardIterator operates in a reverse direction, where the
+ * first item returned by the next() function is from the beginning of the
+ * source sequence.
+ */
+ Backward = 0,
+
+ /**
+ * Signifies the forward direction. Iterators do conceptually operate
+ * in the forward direction by default.
+ */
+ Forward = 1
+ };
+
+ /**
+ * Creates an QAbstractXmlForwardIterator that returns integer values from consecutive sequence
+ * of integers between @p start and @p end, where the step taken
+ * between each integer is 1 with polarity as specified in @p direction.
+ *
+ * @note @p start must be smaller than @p end, not larger
+ * or equal. This is not checked.
+ */
+ RangeIterator(const xsInteger start,
+ const Direction direction,
+ const xsInteger end);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual xsInteger count();
+ virtual Item::Iterator::Ptr toReversed();
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ xsInteger m_start;
+ xsInteger m_end;
+ Item m_current;
+ xsInteger m_position;
+ xsInteger m_count;
+ const Direction m_direction;
+
+ /**
+ * We only need to store -1 or 1, so save memory with a bit field.
+ */
+ const qint8 m_increment : 2;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qremovaliterator.cpp b/src/xmlpatterns/iterators/qremovaliterator.cpp
new file mode 100644
index 0000000..0c0e78d
--- /dev/null
+++ b/src/xmlpatterns/iterators/qremovaliterator.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qremovaliterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+RemovalIterator::RemovalIterator(const Item::Iterator::Ptr &target,
+ const xsInteger pos) : m_target(target),
+ m_removalPos(pos),
+ m_position(0)
+{
+ Q_ASSERT(target);
+ Q_ASSERT(pos >= 1);
+}
+
+Item RemovalIterator::next()
+{
+ if(m_position == -1)
+ return Item();
+
+ m_current = m_target->next();
+
+ if(!m_current)
+ {
+ m_position = -1;
+ m_current.reset();
+ return Item();
+ }
+
+ ++m_position;
+
+ if(m_position == m_removalPos)
+ {
+ next(); /* Recurse, return the next item. */
+ --m_position; /* Don't count the one we removed. */
+ return m_current;
+ }
+
+ return m_current;
+}
+
+xsInteger RemovalIterator::count()
+{
+ const xsInteger itc = m_target->count();
+
+ if(itc < m_removalPos)
+ return itc;
+ else
+ return itc - 1;
+}
+
+Item RemovalIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger RemovalIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr RemovalIterator::copy() const
+{
+ return Item::Iterator::Ptr(new RemovalIterator(m_target->copy(), m_removalPos));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qremovaliterator_p.h b/src/xmlpatterns/iterators/qremovaliterator_p.h
new file mode 100644
index 0000000..0ad130e
--- /dev/null
+++ b/src/xmlpatterns/iterators/qremovaliterator_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_RemovalIterator_H
+#define Patternist_RemovalIterator_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Removes one items at a specified position from an input QAbstractXmlForwardIterator.
+ *
+ * RemoveIterator removes an item from a sequence at a certain position,
+ * while retaining the pull-based characteristic of being an QAbstractXmlForwardIterator itself. The
+ * RemovalIterator's constructor is passed an QAbstractXmlForwardIterator, the QAbstractXmlForwardIterator to
+ * remove from, and the position of the item to remove. When calling the RemovalIterator's
+ * functions, it acts as an ordinary QAbstractXmlForwardIterator, taking into account that
+ * one item is removed from the source QAbstractXmlForwardIterator.
+ *
+ * The RemovalIterator class contains the central business logic for implementing the
+ * <tt>fn:remove()</tt> function, whose definition therefore specifies the detailed behaviors
+ * of RemovalIterator.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-remove">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.1.8 fn:remove</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class RemovalIterator : public Item::Iterator
+ {
+ public:
+
+ /**
+ * Creates an RemovalIterator.
+ *
+ * @param target the QAbstractXmlForwardIterator containing the sequence of items
+ * which the item at position @p position should be removed from.
+ * @param position the position of the item to remove. Must be
+ * 1 or larger.
+ */
+ RemovalIterator(const Item::Iterator::Ptr &target,
+ const xsInteger position);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+
+ /**
+ * The QAbstractXmlForwardIterator's count is computed by subtracting one from the source
+ * QAbstractXmlForwardIterator's count.
+ */
+ virtual xsInteger count();
+
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ const Item::Iterator::Ptr m_target;
+ const xsInteger m_removalPos;
+ Item m_current;
+ xsInteger m_position;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qsequencemappingiterator_p.h b/src/xmlpatterns/iterators/qsequencemappingiterator_p.h
new file mode 100644
index 0000000..3a234f6
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsequencemappingiterator_p.h
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SequenceMappingIterator_H
+#define Patternist_SequenceMappingIterator_H
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qdynamiccontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Proxies another QAbstractXmlForwardIterator, and for each item, returns the
+ * Sequence returned from a mapping function.
+ *
+ * ItemMappingIterator is practical when the items in an QAbstractXmlForwardIterator needs to
+ * be translated to another sequence, while still doing it in a pipe-lined
+ * fashion. In contrast to ItemMappingIterator, SequenceMappingIterator maps
+ * each item into another QAbstractXmlForwardIterator, and where the SequenceMappingIterator's own
+ * result is the concatenation of all those Iterators. Hence, while ItemMappingIterator
+ * is better tailored for one-to-one or one-to-zero conversion, SequenceMappingIterator
+ * is more suitable for one-to-many conversion.
+ *
+ * This is achieved by that SequenceMappingIterator's constructor takes
+ * an instance of a class, that must have the following member:
+ *
+ * @code
+ * QAbstractXmlForwardIterator<TResult>::Ptr mapToSequence(const TSource::Ptr &item,
+ * const DynamicContext::Ptr &context) const;
+ * @endcode
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @see ItemMappingIterator
+ * @ingroup Patternist_iterators
+ */
+ template<typename TResult, typename TSource, typename TMapper>
+ class SequenceMappingIterator : public QAbstractXmlForwardIterator<TResult>
+ {
+ public:
+ /**
+ * Constructs a SequenceMappingIterator.
+ *
+ * @param mapper the object that has the mapToItem() sequence.
+ * @param sourceIterator the QAbstractXmlForwardIterator whose items should be mapped.
+ * @param context the DynamicContext that will be passed to the map function.
+ * May be null.
+ */
+ SequenceMappingIterator(const TMapper &mapper,
+ const typename QAbstractXmlForwardIterator<TSource>::Ptr &sourceIterator,
+ const DynamicContext::Ptr &context);
+
+ virtual TResult next();
+ virtual xsInteger count();
+ virtual TResult current() const;
+ virtual xsInteger position() const;
+
+ /**
+ * The reason the implementation is placed in line here, is due to a bug
+ * in MSVC-2005 version 14.00.50727.762. Note that it works with version 14.00.50727.42.
+ */
+ virtual typename QAbstractXmlForwardIterator<TResult>::Ptr copy() const
+ {
+ return typename QAbstractXmlForwardIterator<TResult>::Ptr
+ (new SequenceMappingIterator<TResult, TSource, TMapper>(m_mapper,
+ m_mainIterator->copy(),
+ m_context));
+ }
+
+ private:
+ xsInteger m_position;
+ TResult m_current;
+ typename QAbstractXmlForwardIterator<TSource>::Ptr m_mainIterator;
+ typename QAbstractXmlForwardIterator<TResult>::Ptr m_currentIterator;
+ const typename DynamicContext::Ptr m_context;
+ const TMapper m_mapper;
+ };
+
+ template<typename TResult, typename TSource, typename TMapper>
+ SequenceMappingIterator<TResult, TSource, TMapper>::SequenceMappingIterator(
+ const TMapper &mapper,
+ const typename QAbstractXmlForwardIterator<TSource>::Ptr &iterator,
+ const DynamicContext::Ptr &context)
+ : m_position(0),
+ m_mainIterator(iterator),
+ m_context(context),
+ m_mapper(mapper)
+ {
+ Q_ASSERT(mapper);
+ Q_ASSERT(iterator);
+ }
+
+ template<typename TResult, typename TSource, typename TMapper>
+ TResult SequenceMappingIterator<TResult, TSource, TMapper>::next()
+ {
+ /* This was once implemented with a recursive function, but the stack
+ * got blown for some inputs by that approach. */
+ while(true)
+ {
+ while(!m_currentIterator)
+ {
+ const TSource mainItem(m_mainIterator->next());
+
+ if(qIsForwardIteratorEnd(mainItem)) /* We've reached the very end. */
+ {
+ m_position = -1;
+ m_current = TResult();
+ return TResult();
+ }
+ else
+ m_currentIterator = m_mapper->mapToSequence(mainItem, m_context);
+ }
+
+ m_current = m_currentIterator->next();
+
+ if(qIsForwardIteratorEnd(m_current))
+ {
+ m_currentIterator.reset();
+ continue;
+ }
+ else
+ {
+ ++m_position;
+ return m_current;
+ }
+ }
+ }
+
+ template<typename TResult, typename TSource, typename TMapper>
+ xsInteger SequenceMappingIterator<TResult, TSource, TMapper>::count()
+ {
+ TSource unit(m_mainIterator->next());
+ xsInteger c = 0;
+
+ while(!qIsForwardIteratorEnd(unit))
+ {
+ const typename QAbstractXmlForwardIterator<TResult>::Ptr sit(m_mapper->mapToSequence(unit, m_context));
+ c += sit->count();
+ unit = m_mainIterator->next();
+ }
+
+ return c;
+ }
+
+ template<typename TResult, typename TSource, typename TMapper>
+ TResult SequenceMappingIterator<TResult, TSource, TMapper>::current() const
+ {
+ return m_current;
+ }
+
+ template<typename TResult, typename TSource, typename TMapper>
+ xsInteger SequenceMappingIterator<TResult, TSource, TMapper>::position() const
+ {
+ return m_position;
+ }
+
+
+ /**
+ * @short An object generator for SequenceMappingIterator.
+ *
+ * makeSequenceMappingIterator() is a convenience function for avoiding specifying
+ * the full template instantiation for SequenceMappingIterator. Conceptually, it
+ * is identical to Qt's qMakePair().
+ *
+ * @returns a SequenceMappingIterator wrapped in a smart pointer, that has been
+ * passed the constructor arguments @p mapper, @p source, and @p context.
+ * @see makeMappingCallbackPtr()
+ * @relates QAbstractXmlForwardIterator
+ */
+ template<typename TResult, typename TSource, typename TMapper>
+ static inline
+ typename QAbstractXmlForwardIterator<TResult>::Ptr
+ makeSequenceMappingIterator(const TMapper &mapper,
+ const QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<TSource> > &source,
+ const DynamicContext::Ptr &context)
+ {
+ return typename QAbstractXmlForwardIterator<TResult>::Ptr
+ (new SequenceMappingIterator<TResult, TSource, TMapper>(mapper, source, context));
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qsingletoniterator_p.h b/src/xmlpatterns/iterators/qsingletoniterator_p.h
new file mode 100644
index 0000000..a6f4cec
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsingletoniterator_p.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SingletonIterator_H
+#define Patternist_SingletonIterator_H
+
+#include <QtXmlPatterns/private/qabstractxmlforwarditerator_p.h>
+
+#include <QtXmlPatterns/private/qprimitives_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short An QAbstractXmlForwardIterator over exactly one item.
+ *
+ * SingletonIterator's constructor takes one value which is
+ * the item it forms an QAbstractXmlForwardIterator over. Other QAbstractXmlForwardIterator instances can
+ * also form an QAbstractXmlForwardIterator with one in length, but by that SingletonIterator
+ * has this as it only task, it means it is efficient at it.
+ *
+ * Having to represent single items in Iterators is relatively common.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ template<typename T>
+ class SingletonIterator : public QAbstractXmlForwardIterator<T>
+ {
+ public:
+ /**
+ * Creates an iterator over @p item.
+ *
+ * @note item may not be @c null. Use the EmptyIterator for
+ * the empty sequence
+ */
+ SingletonIterator(const T &item) : m_item(item),
+ m_position(0)
+ {
+ Q_ASSERT(!qIsForwardIteratorEnd(item));
+ }
+
+ virtual T next()
+ {
+ switch(m_position)
+ {
+ case 0:
+ {
+ ++m_position;
+ return m_item;
+ }
+ case 1:
+ {
+ m_position = -1;
+ return T();
+ }
+ default:
+ {
+ Q_ASSERT(m_position == -1);
+ return T();
+ }
+ }
+ }
+
+ virtual T current() const
+ {
+ if(m_position == 1)
+ return m_item;
+ else
+ return T();
+ }
+
+ virtual xsInteger position() const
+ {
+ return m_position;
+ }
+
+ /**
+ * @returns a copy of this instance, rewinded to the beginning.
+ */
+ virtual typename QAbstractXmlForwardIterator<T>::Ptr toReversed()
+ {
+ return typename QAbstractXmlForwardIterator<T>::Ptr(new SingletonIterator<T>(m_item));
+ }
+
+ /**
+ * @returns always 1
+ */
+ virtual xsInteger count()
+ {
+ return 1;
+ }
+
+ virtual typename QAbstractXmlForwardIterator<T>::Ptr copy() const
+ {
+ return typename QAbstractXmlForwardIterator<T>::Ptr(new SingletonIterator(m_item));
+ }
+
+ private:
+ const T m_item;
+ qint8 m_position;
+ };
+
+ /**
+ * @short An object generator for SingletonIterator.
+ *
+ * makeSingletonIterator() is a convenience function for avoiding specifying
+ * the full template instantiation for SingletonIterator. Conceptually, it
+ * is identical to Qt's qMakePair().
+ *
+ * @relates SingletonIterator
+ */
+ template<typename T>
+ inline
+ typename SingletonIterator<T>::Ptr
+ makeSingletonIterator(const T &item)
+ {
+ return typename SingletonIterator<T>::Ptr(new SingletonIterator<T>(item));
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qsubsequenceiterator.cpp b/src/xmlpatterns/iterators/qsubsequenceiterator.cpp
new file mode 100644
index 0000000..59faf91
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsubsequenceiterator.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxpathhelper_p.h"
+
+#include "qsubsequenceiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SubsequenceIterator::SubsequenceIterator(const Item::Iterator::Ptr &iterator,
+ const xsInteger start,
+ const xsInteger len)
+ : m_position(0),
+ m_it(iterator),
+ m_counter(start),
+ m_start(start),
+ m_len(len),
+ m_stop(m_start + m_len)
+{
+ Q_ASSERT(iterator);
+ Q_ASSERT(start >= 1);
+ Q_ASSERT(len == -1 || len >= 1);
+
+ /* Note, "The first item of a sequence is located at position 1, not position 0." */
+ for(xsInteger i = 1; i != m_start; ++i)
+ m_it->next();
+}
+
+Item SubsequenceIterator::next()
+{
+ if(m_position == -1)
+ return Item();
+
+ m_current = m_it->next();
+ ++m_position;
+
+ if(m_len == -1)
+ {
+ if(!m_current)
+ m_position = -1;
+
+ return m_current;
+ }
+
+ ++m_counter;
+
+ if(!(m_counter > m_stop) && m_current)
+ return m_current;
+
+ m_position = -1;
+ m_current.reset();
+ return Item();
+}
+
+Item SubsequenceIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger SubsequenceIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr SubsequenceIterator::copy() const
+{
+ return Item::Iterator::Ptr(new SubsequenceIterator(m_it->copy(), m_start, m_len));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qsubsequenceiterator_p.h b/src/xmlpatterns/iterators/qsubsequenceiterator_p.h
new file mode 100644
index 0000000..5530297
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsubsequenceiterator_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SubsequenceIterator_H
+#define Patternist_SubsequenceIterator_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Picks out a slice from another QAbstractXmlForwardIterator, specified by a start and end position.
+ *
+ * SubsequenceIterator allows a "slice", a subsequence, from an QAbstractXmlForwardIterator to
+ * be extracted. The SubsequenceIterator's constructor takes a source QAbstractXmlForwardIterator,
+ * a start position, and the length of the subsequence to be extracted.
+ *
+ * SubsequenceIterator contains the central business logic to implement
+ * the <tt>fn:subsequence()</tt> function. The detailed behavior, such as how it behaves
+ * if the source QAbstractXmlForwardIterator is empty or if the specified subsequence stretches
+ * beyond the source QAbstractXmlForwardIterator, is therefore consistent with the definition of
+ * the <tt>fn:subsequence()</tt> function.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-subsequence">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 15.1.10 fn:subsequence</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class SubsequenceIterator : public Item::Iterator
+ {
+ public:
+ /**
+ * Creates a SubsequenceIterator that extracts a subsequence from the sequence
+ * in @p iterator, as specified by the @p start position and @p length parameter.
+ *
+ * @param iterator the iterator which the subsequence should
+ * be extracted from
+ * @param start the start position of extraction. Must be 1 or larger.
+ * @param length the length of the subsequence to extract. If it is
+ * -1, to the end is returned. The value must be -1 or 1 or larger.
+ */
+ SubsequenceIterator(const Item::Iterator::Ptr &iterator,
+ const xsInteger start,
+ const xsInteger length);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ xsInteger m_position;
+ Item m_current;
+ const Item::Iterator::Ptr m_it;
+ xsInteger m_counter;
+ const xsInteger m_start;
+ const xsInteger m_len;
+ const xsInteger m_stop;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qtocodepointsiterator.cpp b/src/xmlpatterns/iterators/qtocodepointsiterator.cpp
new file mode 100644
index 0000000..5adf314
--- /dev/null
+++ b/src/xmlpatterns/iterators/qtocodepointsiterator.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qinteger_p.h"
+
+#include "qtocodepointsiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ToCodepointsIterator::ToCodepointsIterator(const QString &string)
+ : m_string(string),
+ m_len(string.length()),
+ m_position(0)
+{
+ Q_ASSERT(!string.isEmpty());
+}
+
+Item ToCodepointsIterator::next()
+{
+ if(m_position == -1)
+ return Item();
+
+ ++m_position;
+ if(m_position > m_len)
+ {
+ m_position = -1;
+ m_current.reset();
+ return m_current;
+ }
+
+ m_current = Integer::fromValue(m_string.at(m_position - 1).unicode());
+ return m_current;
+}
+
+xsInteger ToCodepointsIterator::count()
+{
+ return m_len;
+}
+
+Item ToCodepointsIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger ToCodepointsIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr ToCodepointsIterator::copy() const
+{
+ return Item::Iterator::Ptr(new ToCodepointsIterator(m_string));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qtocodepointsiterator_p.h b/src/xmlpatterns/iterators/qtocodepointsiterator_p.h
new file mode 100644
index 0000000..413c4bc
--- /dev/null
+++ b/src/xmlpatterns/iterators/qtocodepointsiterator_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ToCodepointsIterator_H
+#define Patternist_ToCodepointsIterator_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a stream of Unicode codepoints, which are computed from a string.
+ *
+ * ToCodepointsIterator takes in its constructor a string, whose Unicode characters'
+ * codepoints it forms an QAbstractXmlForwardIterator over.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-string-to-codepoints">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 7.2.2 fn:string-to-codepoints</a>
+ * @see StringToCodepointsFN
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_iterators
+ */
+ class ToCodepointsIterator : public Item::Iterator
+ {
+ public:
+ /**
+ * Constructs a ToCodepointsIterator.
+ *
+ * @param string the string to retrieve Unicode codepoints from. Can not be
+ * empty.
+ */
+ ToCodepointsIterator(const QString &string);
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual xsInteger count();
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ const QString m_string;
+ const int m_len;
+ Item m_current;
+ xsInteger m_position;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/qunioniterator.cpp b/src/xmlpatterns/iterators/qunioniterator.cpp
new file mode 100644
index 0000000..e0166c1
--- /dev/null
+++ b/src/xmlpatterns/iterators/qunioniterator.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+
+#include "qunioniterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UnionIterator::UnionIterator(const Item::Iterator::Ptr &it1,
+ const Item::Iterator::Ptr &it2) : m_it1(it1),
+ m_it2(it2),
+ m_position(0),
+ m_node1(m_it1->next()),
+ m_node2(m_it2->next())
+{
+ Q_ASSERT(m_it1);
+ Q_ASSERT(m_it2);
+}
+
+Item UnionIterator::next()
+{
+ ++m_position;
+ if(m_node1 && m_node2)
+ {
+ if(m_node1.asNode().model() != m_node2.asNode().model())
+ {
+ m_current = m_node1;
+ m_node1 = m_it1->next();
+ return m_current;
+ }
+
+ switch(m_node1.asNode().compareOrder(m_node2.asNode()))
+ {
+ case QXmlNodeModelIndex::Precedes:
+ {
+ m_current = m_node1;
+ m_node1 = m_it1->next();
+ return m_current;
+ }
+ case QXmlNodeModelIndex::Follows:
+ {
+ m_current = m_node2;
+ m_node2 = m_it2->next();
+ return m_current;
+ }
+ default:
+ {
+ m_current = m_node2;
+ m_node1 = m_it1->next();
+ m_node2 = m_it2->next();
+ return m_current;
+ }
+ }
+ }
+
+ if(m_node1)
+ {
+ m_current = m_node1;
+ m_node1 = m_it1->next();
+ return m_current;
+ }
+
+ if(m_node2)
+ {
+ m_current = m_node2;
+ m_node2 = m_it2->next();
+ return m_current;
+ }
+
+ m_current.reset();
+ m_position = -1;
+ return Item();
+}
+
+Item UnionIterator::current() const
+{
+ return m_current;
+}
+
+xsInteger UnionIterator::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr UnionIterator::copy() const
+{
+ return Item::Iterator::Ptr(new UnionIterator(m_it1->copy(), m_it2->copy()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/iterators/qunioniterator_p.h b/src/xmlpatterns/iterators/qunioniterator_p.h
new file mode 100644
index 0000000..2218180
--- /dev/null
+++ b/src/xmlpatterns/iterators/qunioniterator_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UnionIterator_H
+#define Patternist_UnionIterator_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the @c except operator. That is, the computation
+ * of the sequence of nodes from one sequence, that doesn't appear in the
+ * other.
+ *
+ * @ingroup Patternist_iterators
+ */
+ class UnionIterator : public Item::Iterator
+ {
+ public:
+ /**
+ * It is assumed that @p it1 and @p it2 are in document order and
+ * without duplicates.
+ */
+ UnionIterator(const Item::Iterator::Ptr &it1,
+ const Item::Iterator::Ptr &it2);
+
+ virtual Item next();
+ virtual Item current() const;
+ virtual xsInteger position() const;
+ virtual Item::Iterator::Ptr copy() const;
+
+ private:
+ inline Item nextFromFirstOperand()
+ {
+ ++m_position;
+ m_current = m_node1;
+ m_node1 = m_it1->next();
+ return m_current;
+ }
+
+ const Item::Iterator::Ptr m_it1;
+ const Item::Iterator::Ptr m_it2;
+ Item m_current;
+ xsInteger m_position;
+ Item m_node1;
+ Item m_node2;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/janitors/janitors.pri b/src/xmlpatterns/janitors/janitors.pri
new file mode 100644
index 0000000..25de3a4
--- /dev/null
+++ b/src/xmlpatterns/janitors/janitors.pri
@@ -0,0 +1,13 @@
+HEADERS += $$PWD/qargumentconverter_p.h \
+ $$PWD/qatomizer_p.h \
+ $$PWD/qcardinalityverifier_p.h \
+ $$PWD/qebvextractor_p.h \
+ $$PWD/qitemverifier_p.h \
+ $$PWD/quntypedatomicconverter_p.h
+
+SOURCES += $$PWD/qargumentconverter.cpp \
+ $$PWD/qatomizer.cpp \
+ $$PWD/qcardinalityverifier.cpp \
+ $$PWD/qebvextractor.cpp \
+ $$PWD/qitemverifier.cpp \
+ $$PWD/quntypedatomicconverter.cpp
diff --git a/src/xmlpatterns/janitors/qargumentconverter.cpp b/src/xmlpatterns/janitors/qargumentconverter.cpp
new file mode 100644
index 0000000..bf4c431
--- /dev/null
+++ b/src/xmlpatterns/janitors/qargumentconverter.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitemmappingiterator_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qargumentconverter_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ArgumentConverter::ArgumentConverter(const Expression::Ptr &operand,
+ const ItemType::Ptr &reqType) : UntypedAtomicConverter(operand, reqType)
+{
+}
+
+ExpressionVisitorResult::Ptr ArgumentConverter::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Item::Iterator::Ptr ArgumentConverter::mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ if(item.isAtomicValue() && !BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(item.type()))
+ return makeSingletonIterator(item);
+ else
+ {
+ /* We're using UntypedAtomicConverter::mapToItem(). */
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ item.sequencedTypedValue(),
+ context);
+ }
+}
+
+Item::Iterator::Ptr ArgumentConverter::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ m_operand->evaluateSequence(context),
+ context);
+}
+
+Item ArgumentConverter::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ if(item)
+ return mapToItem(item, context);
+ else /* Empty is allowed. ArgumentConverter doesn't care about cardinality. */
+ return Item();
+}
+
+SequenceType::List ArgumentConverter::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr ArgumentConverter::staticType() const
+{
+ return CommonSequenceTypes::ZeroOrMoreAtomicTypes;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/janitors/qargumentconverter_p.h b/src/xmlpatterns/janitors/qargumentconverter_p.h
new file mode 100644
index 0000000..244507f
--- /dev/null
+++ b/src/xmlpatterns/janitors/qargumentconverter_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ArgumentConverter_H
+#define Patternist_ArgumentConverter_H
+
+#include "quntypedatomicconverter_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short UntypedAtomicConverter for ArgumentReference, if needed.
+ *
+ * If an argument inside a user function has no type declared, its type
+ * is @c item(). It's atomized type would be inferred to @c
+ * xs:anyAtomicType, but that is not necessarily correct, since the actual
+ * value can be anything, nodes or atomic values.
+ *
+ * This extremely dynamic case is handled by ArgumentConverter which is inserted for
+ * ArgumentReference that has the static type @c item(), when atomic value are asked
+ * for. At runtime it atomizes/let values through appropriately.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ArgumentConverter : public UntypedAtomicConverter
+ {
+ public:
+ ArgumentConverter(const Expression::Ptr &operand,
+ const ItemType::Ptr &reqType);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const ArgumentConverter> ConstPtr;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/janitors/qatomizer.cpp b/src/xmlpatterns/janitors/qatomizer.cpp
new file mode 100644
index 0000000..ae4b597
--- /dev/null
+++ b/src/xmlpatterns/janitors/qatomizer.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qatomizer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Atomizer::Atomizer(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+Item::Iterator::Ptr Atomizer::mapToSequence(const Item &item, const DynamicContext::Ptr &) const
+{
+ /* Function & Operators, 2.4.2 fn:data, says "If the node does not have a
+ * typed value an error is raised [err:FOTY0012]."
+ * When does a node not have a typed value? */
+ Q_ASSERT(item);
+ return item.sequencedTypedValue();
+}
+
+Item::Iterator::Ptr Atomizer::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ m_operand->evaluateSequence(context),
+ context);
+}
+
+Item Atomizer::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ if(!item) /* Empty is allowed, cardinality is considered '?' */
+ return Item();
+
+ const Item::Iterator::Ptr it(mapToSequence(item, context));
+ Q_ASSERT_X(it, Q_FUNC_INFO, "A valid QAbstractXmlForwardIterator must always be returned.");
+
+ Item result(it->next());
+ Q_ASSERT_X(!it->next(), Q_FUNC_INFO,
+ "evaluateSingleton should never be used if the cardinality is two or more");
+
+ return result;
+}
+
+Expression::Ptr Atomizer::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* Compress -- the earlier the better. */
+ if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(m_operand->staticType()->itemType()))
+ return m_operand->typeCheck(context, reqType);
+
+ return SingleContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr Atomizer::staticType() const
+{
+ const SequenceType::Ptr opt(m_operand->staticType());
+ return makeGenericSequenceType(opt->itemType()->atomizedType(),
+ opt->cardinality());
+}
+
+SequenceType::List Atomizer::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr Atomizer::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *Atomizer::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/janitors/qatomizer_p.h b/src/xmlpatterns/janitors/qatomizer_p.h
new file mode 100644
index 0000000..0dc54a6
--- /dev/null
+++ b/src/xmlpatterns/janitors/qatomizer_p.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Atomizer_H
+#define Patternist_Atomizer_H
+
+#include "qitem_p.h"
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Performs atomization. Effectively, it is an implementation
+ * of the <tt>fn:data()</tt> function.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-data">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators, 2.4 fn:data</a>
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-atomization">XML
+ * Path Language (XPath) 2.0, 2.4.2 Atomization</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Atomizer : public SingleContainer
+ {
+ public:
+ Atomizer(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ /**
+ * Makes an early compression, by returning the result of
+ * the type checked operand, if the operand has the static type
+ * xs:anyAtomicType(no atomization needed).
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const Atomizer> ConstPtr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/janitors/qcardinalityverifier.cpp b/src/xmlpatterns/janitors/qcardinalityverifier.cpp
new file mode 100644
index 0000000..7b56dbb
--- /dev/null
+++ b/src/xmlpatterns/janitors/qcardinalityverifier.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qgenericpredicate_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qinsertioniterator_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qcardinalityverifier_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QString CardinalityVerifier::wrongCardinality(const Cardinality &req,
+ const Cardinality &got)
+{
+ return QtXmlPatterns::tr("Required cardinality is %1; got cardinality %2.")
+ .arg(formatType(req), formatType(got));
+}
+
+Expression::Ptr CardinalityVerifier::verifyCardinality(const Expression::Ptr &operand,
+ const Cardinality &requiredCard,
+ const StaticContext::Ptr &context,
+ const ReportContext::ErrorCode code)
+{
+ const Cardinality opCard(operand->staticType()->cardinality());
+
+ if(requiredCard.isMatch(opCard))
+ return operand;
+ else if(requiredCard.canMatch(opCard))
+ return Expression::Ptr(new CardinalityVerifier(operand, requiredCard, code));
+ else if(context->compatModeEnabled() &&
+ !opCard.isEmpty())
+ {
+ return GenericPredicate::createFirstItem(operand);
+ }
+ else
+ {
+ /* Sequences within this cardinality can never match. */
+ context->error(wrongCardinality(requiredCard, opCard), code, operand.data());
+ return operand;
+ }
+}
+
+CardinalityVerifier::CardinalityVerifier(const Expression::Ptr &operand,
+ const Cardinality &card,
+ const ReportContext::ErrorCode code)
+ : SingleContainer(operand),
+ m_reqCard(card),
+ m_allowsMany(operand->staticType()->cardinality().allowsMany()),
+ m_errorCode(code)
+{
+ Q_ASSERT_X(m_reqCard != Cardinality::zeroOrMore(), Q_FUNC_INFO,
+ "It makes no sense to use CardinalityVerifier for cardinality zero-or-more.");
+}
+
+Item::Iterator::Ptr CardinalityVerifier::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ const Item next(it->next());
+
+ if(next)
+ {
+ const Item next2(it->next());
+
+ if(next2)
+ {
+ if(m_reqCard.allowsMany())
+ {
+ Item::List start;
+ start.append(next);
+ start.append(next2);
+
+ return Item::Iterator::Ptr(new InsertionIterator(it, 1, makeListIterator(start)));
+ }
+ else
+ {
+ context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()), m_errorCode, this);
+ return CommonValues::emptyIterator;
+ }
+ }
+ else
+ {
+ /* We might be instantiated for the empty sequence. */
+ if(m_reqCard.isEmpty())
+ {
+ context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()), m_errorCode, this);
+ return CommonValues::emptyIterator;
+ }
+ else
+ return makeSingletonIterator(next);
+ }
+ }
+ else
+ {
+ if(m_reqCard.allowsEmpty())
+ return CommonValues::emptyIterator;
+ else
+ {
+ context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()), m_errorCode, this);
+ return CommonValues::emptyIterator;
+ }
+ }
+}
+
+Item CardinalityVerifier::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ if(m_allowsMany)
+ {
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ const Item item(it->next());
+
+ if(item)
+ {
+ if(it->next())
+ {
+ context->error(wrongCardinality(m_reqCard, Cardinality::twoOrMore()),
+ m_errorCode, this);
+ return Item();
+ }
+ else
+ return item;
+ }
+ else if(m_reqCard.allowsEmpty())
+ return Item();
+ else
+ {
+ context->error(wrongCardinality(m_reqCard), m_errorCode, this);
+ return Item();
+ }
+ }
+ else
+ {
+ const Item item(m_operand->evaluateSingleton(context));
+
+ if(item)
+ return item;
+ else if(m_reqCard.allowsEmpty())
+ return Item();
+ else
+ {
+ context->error(wrongCardinality(m_reqCard), m_errorCode, this);
+ return Item();
+ }
+ }
+}
+
+const SourceLocationReflection *CardinalityVerifier::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+Expression::Ptr CardinalityVerifier::compress(const StaticContext::Ptr &context)
+{
+ if(m_reqCard.isMatch(m_operand->staticType()->cardinality()))
+ return m_operand->compress(context);
+ else
+ return SingleContainer::compress(context);
+}
+
+SequenceType::List CardinalityVerifier::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr CardinalityVerifier::staticType() const
+{
+ return makeGenericSequenceType(m_operand->staticType()->itemType(), m_reqCard);
+}
+
+ExpressionVisitorResult::Ptr CardinalityVerifier::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID CardinalityVerifier::id() const
+{
+ return IDCardinalityVerifier;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/janitors/qcardinalityverifier_p.h b/src/xmlpatterns/janitors/qcardinalityverifier_p.h
new file mode 100644
index 0000000..b5e7342
--- /dev/null
+++ b/src/xmlpatterns/janitors/qcardinalityverifier_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CardinalityVerifier_H
+#define Patternist_CardinalityVerifier_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Verifies that the sequence an Expression evaluates to conforms to a Cardinality.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#cardinality-funcs">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 15.2 Functions That Test the Cardinality of Sequences</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CardinalityVerifier : public SingleContainer
+ {
+ public:
+ CardinalityVerifier(const Expression::Ptr &operand,
+ const Cardinality &card,
+ const ReportContext::ErrorCode code);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * If the static cardinality of the operand is within the required cardinality,
+ * the operand is returned as is, since results will always be valid and hence
+ * is not a CardinalityVerifier necessary.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * A utility function for determining whether the static type of an Expression matches
+ * a cardinality. More specifically, this function performs the cardinality verification
+ * part of the Function Conversion Rules.
+ *
+ * @todo Mention the rewrite and when exactly an error is issued via @p context
+ */
+ static Expression::Ptr
+ verifyCardinality(const Expression::Ptr &operand,
+ const Cardinality &card,
+ const StaticContext::Ptr &context,
+ const ReportContext::ErrorCode code = ReportContext::XPTY0004);
+
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ ID id() const;
+ private:
+ /**
+ * Centralizes a message string in order to increase consistency and
+ * reduce work for translators.
+ */
+ static inline QString wrongCardinality(const Cardinality &req,
+ const Cardinality &got = Cardinality::empty());
+
+ const Cardinality m_reqCard;
+ const bool m_allowsMany;
+ const ReportContext::ErrorCode m_errorCode;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/janitors/qebvextractor.cpp b/src/xmlpatterns/janitors/qebvextractor.cpp
new file mode 100644
index 0000000..df06642
--- /dev/null
+++ b/src/xmlpatterns/janitors/qebvextractor.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qebvextractor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+EBVExtractor::EBVExtractor(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+bool EBVExtractor::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand->evaluateEBV(context);
+}
+
+Expression::Ptr EBVExtractor::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ return typeCheck<SingleContainer>(context, reqType, this);
+}
+
+SequenceType::Ptr EBVExtractor::staticType() const
+{
+ return makeGenericSequenceType(BuiltinTypes::xsBoolean, Cardinality::exactlyOne());
+}
+
+SequenceType::List EBVExtractor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+const SourceLocationReflection *EBVExtractor::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+ExpressionVisitorResult::Ptr EBVExtractor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/janitors/qebvextractor_p.h b/src/xmlpatterns/janitors/qebvextractor_p.h
new file mode 100644
index 0000000..22d3d7a
--- /dev/null
+++ b/src/xmlpatterns/janitors/qebvextractor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_EBVExtractor_H
+#define Patternist_EBVExtractor_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Calculates the Effective Boolean Value of its operand.
+ *
+ * EBVExtractor performs functionality wise the same as @c fn:boolean(),
+ * but does it without the dependencies which FunctionCall requires.
+ *
+ * There is code-duplication going on with BooleanFN.
+ *
+ * @see BooleanFN
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class EBVExtractor : public SingleContainer
+ {
+ public:
+ EBVExtractor(const Expression::Ptr &operand);
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @short Returns always @c xs:boolean.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ template<typename TSubClass, typename ThisType>
+ static Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType,
+ ThisType *const caller)
+ {
+ if(*CommonSequenceTypes::EBV->itemType() == *reqType->itemType())
+ return caller->operands().first()->typeCheck(context, reqType);
+ else
+ return caller->TSubClass::typeCheck(context, reqType);
+ }
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/janitors/qitemverifier.cpp b/src/xmlpatterns/janitors/qitemverifier.cpp
new file mode 100644
index 0000000..7c7f555
--- /dev/null
+++ b/src/xmlpatterns/janitors/qitemverifier.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qitemverifier_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ItemVerifier::ItemVerifier(const Expression::Ptr &operand,
+ const ItemType::Ptr &reqType,
+ const ReportContext::ErrorCode errorCode) : SingleContainer(operand),
+ m_reqType(reqType),
+ m_errorCode(errorCode)
+{
+ Q_ASSERT(reqType);
+}
+
+void ItemVerifier::verifyItem(const Item &item, const DynamicContext::Ptr &context) const
+{
+ if(m_reqType->itemMatches(item))
+ return;
+
+ context->error(QtXmlPatterns::tr("The item %1 did not match the required type %2.")
+ .arg(formatData(item.stringValue()),
+ formatType(context->namePool(), m_reqType)),
+ m_errorCode,
+ this);
+}
+
+const SourceLocationReflection *ItemVerifier::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+Item ItemVerifier::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ if(item)
+ {
+ verifyItem(item, context);
+ return item;
+ }
+ else
+ return Item();
+}
+
+Item ItemVerifier::mapToItem(const Item &item, const DynamicContext::Ptr &context) const
+{
+ verifyItem(item, context);
+ return item;
+}
+
+Item::Iterator::Ptr ItemVerifier::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ m_operand->evaluateSequence(context),
+ context);
+}
+
+SequenceType::Ptr ItemVerifier::staticType() const
+{
+ return makeGenericSequenceType(m_reqType, m_operand->staticType()->cardinality());
+}
+
+SequenceType::List ItemVerifier::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr ItemVerifier::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/janitors/qitemverifier_p.h b/src/xmlpatterns/janitors/qitemverifier_p.h
new file mode 100644
index 0000000..0500425
--- /dev/null
+++ b/src/xmlpatterns/janitors/qitemverifier_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ItemVerifier_H
+#define Patternist_ItemVerifier_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Verifies that the items in a sequence an Expression evaluates
+ * is of a certain ItemType.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ItemVerifier : public SingleContainer
+ {
+ public:
+
+ ItemVerifier(const Expression::Ptr &operand,
+ const ItemType::Ptr &reqType,
+ const ReportContext::ErrorCode errorCode);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ inline Item mapToItem(const Item &, const DynamicContext::Ptr &) const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const ItemVerifier> ConstPtr;
+ inline void verifyItem(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ const ItemType::Ptr m_reqType;
+ const ReportContext::ErrorCode m_errorCode;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/janitors/quntypedatomicconverter.cpp b/src/xmlpatterns/janitors/quntypedatomicconverter.cpp
new file mode 100644
index 0000000..4143315
--- /dev/null
+++ b/src/xmlpatterns/janitors/quntypedatomicconverter.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+
+#include "quntypedatomicconverter_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UntypedAtomicConverter::UntypedAtomicConverter(const Expression::Ptr &operand,
+ const ItemType::Ptr &reqType,
+ const ReportContext::ErrorCode code) : SingleContainer(operand)
+ , CastingPlatform<UntypedAtomicConverter, true>(code)
+ , m_reqType(reqType)
+{
+ Q_ASSERT(reqType);
+}
+
+Item::Iterator::Ptr UntypedAtomicConverter::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ m_operand->evaluateSequence(context),
+ context);
+}
+
+Item UntypedAtomicConverter::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ if(item)
+ return cast(item, context);
+ else /* Empty is allowed. UntypedAtomicConverter doesn't care about cardinality. */
+ return Item();
+}
+
+Expression::Ptr UntypedAtomicConverter::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+
+ /* Let the CastingPlatform look up its AtomicCaster. */
+ prepareCasting(context, m_operand->staticType()->itemType());
+
+ return me;
+}
+
+SequenceType::List UntypedAtomicConverter::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ return result;
+}
+
+SequenceType::Ptr UntypedAtomicConverter::staticType() const
+{
+ return makeGenericSequenceType(m_reqType,
+ m_operand->staticType()->cardinality());
+}
+
+ExpressionVisitorResult::Ptr UntypedAtomicConverter::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *UntypedAtomicConverter::actualReflection() const
+{
+ return m_operand.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/janitors/quntypedatomicconverter_p.h b/src/xmlpatterns/janitors/quntypedatomicconverter_p.h
new file mode 100644
index 0000000..016718a
--- /dev/null
+++ b/src/xmlpatterns/janitors/quntypedatomicconverter_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_UntypedAtomicConverter_H
+#define Patternist_UntypedAtomicConverter_H
+
+#include "qitem_p.h"
+#include "qsinglecontainer_p.h"
+#include "qcastingplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Casts every item in a sequence obtained from
+ * evaluating an Expression, to a requested atomic type.
+ *
+ * The atomic values it casts from are instances of xs:untypedAtomic(hence
+ * the name). Typically, the items are from an Atomizer. UntypedAtomicConverter
+ * implements the automatic conversion which typically is activated when XPath
+ * is handling untyped data.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-function-calls">XML Path
+ * Language (XPath) 2.0, 3.1.5 Function Calls, in particular the
+ * Function Conversion Rules</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UntypedAtomicConverter : public SingleContainer,
+ public CastingPlatform<UntypedAtomicConverter, true>
+ {
+ public:
+ UntypedAtomicConverter(const Expression::Ptr &operand,
+ const ItemType::Ptr &reqType,
+ const ReportContext::ErrorCode code = ReportContext::FORG0001);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Overridden to call CastingPlatform::typeCheck()
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ inline Item mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ inline ItemType::Ptr targetType() const
+ {
+ return m_reqType;
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const UntypedAtomicConverter> ConstPtr;
+ const ItemType::Ptr m_reqType;
+ };
+
+ Item UntypedAtomicConverter::mapToItem(const Item &item, const DynamicContext::Ptr &context) const
+ {
+ return cast(item, context);
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/.gitattributes b/src/xmlpatterns/parser/.gitattributes
new file mode 100644
index 0000000..61b39a8
--- /dev/null
+++ b/src/xmlpatterns/parser/.gitattributes
@@ -0,0 +1,4 @@
+qquerytransformparser.cpp -diff Unset
+qquerytransformparser_p.h -diff Unset
+qxslttokenlookup.cpp -diff Unset
+qxslttokenlookup_p.h -diff Unset
diff --git a/src/xmlpatterns/parser/.gitignore b/src/xmlpatterns/parser/.gitignore
new file mode 100644
index 0000000..615637a
--- /dev/null
+++ b/src/xmlpatterns/parser/.gitignore
@@ -0,0 +1 @@
+qquerytransformparser.output
diff --git a/src/xmlpatterns/parser/TokenLookup.gperf b/src/xmlpatterns/parser/TokenLookup.gperf
new file mode 100644
index 0000000..491e925
--- /dev/null
+++ b/src/xmlpatterns/parser/TokenLookup.gperf
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file qtokenlookup.cpp
+ * @short This file is generated from TokenLookup.gperf and contains
+ * TokenLookup, a class housing a perfect hash function class for XQuery's keywords.
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+/**
+ * @class QPatternist::TokenLookup
+ * @short Contains a perfect hash function for XQuery's keywords.
+ */
+
+/**
+ * @fn QPatternist::TokenLookup::value(const QString &keyword)
+ * Looks up @p keyword and returns a pointer to the corresponding value.
+ *
+ * If @p keyword is not contained in the hash, a null pointer is returned.
+ */
+
+/**
+ * @file
+ * @short This file is the @c gperf declaration for generating TokenLookup.cpp.
+ *
+ * You generate TokenLookup.cpp by running:
+ *
+ * @code
+ * gperf TokenLookup.gperf --output-file=../src/parser/TokenLookup.cpp
+ * @endcode
+ *
+ * @c gperf generates a perfect hash function, which the tokenizer, src/parser/qxquerytokenizer.cpp,
+ * uses for looking up XQuery keywords.
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Perfect_hash_function">Perfect hash function, Wikipedia</a>
+ * @see <a href="http://www.gnu.org/software/gperf/manual/gperf.html">Perfect Hash Function Generator</a>
+ */
+
+%language=C++
+
+/* Declare data const such that the compiler can put them
+ * in the read-only section. */
+%readonly-tables
+
+/* Yes, for crisps sake, we want enums instead of macros. */
+%enum
+
+/* Rename in_word_set to value, such that it's more
+ * like QHash::value(). */
+%define lookup-function-name value
+
+/* Rename Perfect_Hash to TokenLookup. More Qt/Patternist'ish. */
+%define class-name TokenLookup
+
+/* Output initializers for the TokenMap struct. Note the lack
+ * of a space between the comma and ERROR. Anything else is
+ * a syntax error to gperf. Rocket science. */
+%define initializer-suffix ,ERROR
+
+%struct-type
+
+struct TokenMap
+{
+ const char *name;
+ const Tokenizer::TokenType token;
+}
+
+%{
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+%}
+
+/* The strings below are in UTF-16 encoding. Subsequently, each ASCII
+ * character is stored as the ASCII character, followed by a null byte.
+ * Sorted alphabetically. */
+%%
+"ancestor", ANCESTOR
+"ancestor-or-self", ANCESTOR_OR_SELF
+"and", AND
+"as", AS
+"ascending", ASCENDING
+"assign", ASSIGN
+"at", AT
+"attribute", ATTRIBUTE
+"base-uri", BASEURI
+"boundary-space", BOUNDARY_SPACE
+"by", BY
+"case", CASE
+"castable", CASTABLE
+"cast", CAST
+"child", CHILD
+"collation", COLLATION
+"comment", COMMENT
+"construction", CONSTRUCTION
+"copy-namespaces", COPY_NAMESPACES
+"declare", DECLARE
+"default", DEFAULT
+"descendant", DESCENDANT
+"descendant-or-self", DESCENDANT_OR_SELF
+"descending", DESCENDING
+"div", DIV
+"document", DOCUMENT
+"document-node", DOCUMENT_NODE
+"element", ELEMENT
+"else", ELSE
+"empty", EMPTY
+"empty-sequence", EMPTY_SEQUENCE
+"encoding", ENCODING
+"eq", EQ
+"every", EVERY
+"except", EXCEPT
+"external", EXTERNAL
+"following", FOLLOWING
+"following-sibling", FOLLOWING_SIBLING
+"follows", FOLLOWS
+"for", FOR
+"function", FUNCTION
+"ge", GE
+"greatest", GREATEST
+"gt", GT
+"idiv", IDIV
+"if", IF
+"import", IMPORT
+"inherit", INHERIT
+"in", IN
+"instance", INSTANCE
+"intersect", INTERSECT
+"is", IS
+"item", ITEM
+"lax", LAX
+"least", LEAST
+"le", LE
+"let", LET
+"lt", LT
+"mod", MOD
+"module", MODULE
+"namespace", NAMESPACE
+"ne", NE
+"node", NODE
+"no-inherit", NO_INHERIT
+"no-preserve", NO_PRESERVE
+"of", OF
+"option", OPTION
+"ordered", ORDERED
+"ordering", ORDERING
+"order", ORDER
+"or", OR
+"parent", PARENT
+"precedes", PRECEDES
+"preceding", PRECEDING
+"preceding-sibling", PRECEDING_SIBLING
+"preserve", PRESERVE
+"processing-instruction", PROCESSING_INSTRUCTION
+"return", RETURN
+"satisfies", SATISFIES
+"schema-attribute", SCHEMA_ATTRIBUTE
+"schema-element", SCHEMA_ELEMENT
+"schema", SCHEMA
+"self", SELF
+"some", SOME
+"stable", STABLE
+"strict", STRICT
+"strip", STRIP
+"text", TEXT
+"then", THEN
+"to", TO
+"treat", TREAT
+"typeswitch", TYPESWITCH
+"union", UNION
+"unordered", UNORDERED
+"validate", VALIDATE
+"variable", VARIABLE
+"version", VERSION
+"where", WHERE
+"xquery", XQUERY
+%%
+
+} /* Close the QPatternist namespace. */
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/createParser.sh b/src/xmlpatterns/parser/createParser.sh
new file mode 100755
index 0000000..5673abc
--- /dev/null
+++ b/src/xmlpatterns/parser/createParser.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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 Technology Preview License Agreement accompanying
+## this package.
+##
+## 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+files="qquerytransformparser_p.h qquerytransformparser.cpp"
+
+#p4 revert $files
+#p4 edit $files
+bison --defines=qquerytransformparser_p.h querytransformparser.ypp
+
+addHeaderScript="1{h; r trolltechHeader.txt
+ D; }
+2{x; G; }"
+sed -i -e "$addHeaderScript" $files
+
+sed -i -f winCEWorkaround.sed qquerytransformparser_p.h
+#p4 revert -a $files
diff --git a/src/xmlpatterns/parser/createTokenLookup.sh b/src/xmlpatterns/parser/createTokenLookup.sh
new file mode 100755
index 0000000..6083732
--- /dev/null
+++ b/src/xmlpatterns/parser/createTokenLookup.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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 Technology Preview License Agreement accompanying
+## this package.
+##
+## 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+outFile="qtokenlookup.cpp"
+
+license=`cat <<EOF
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** \\$QT_END_LICENSE\\$
+**
+****************************************************************************/
+EOF`
+echo "$license" > $outFile
+
+# Watch out, the --output option is not supported in the
+# gperf version that apt-get pulls in on Mac OS X.
+gperf TokenLookup.gperf >> $outFile
diff --git a/src/xmlpatterns/parser/createXSLTTokenLookup.sh b/src/xmlpatterns/parser/createXSLTTokenLookup.sh
new file mode 100755
index 0000000..a36d76f
--- /dev/null
+++ b/src/xmlpatterns/parser/createXSLTTokenLookup.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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 Technology Preview License Agreement accompanying
+## this package.
+##
+## 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+xmllint --noout --schema ../qtokenautomaton/qtokenautomaton.xsd qxslttokenlookup.xml
+java net.sf.saxon.Transform -xsl:../qtokenautomaton/qautomaton2cpp.xsl qxslttokenlookup.xml
diff --git a/src/xmlpatterns/parser/parser.pri b/src/xmlpatterns/parser/parser.pri
new file mode 100644
index 0000000..6656290
--- /dev/null
+++ b/src/xmlpatterns/parser/parser.pri
@@ -0,0 +1,19 @@
+hpux-g++*:QMAKE_CXXFLAGS += -mbig-switch
+
+HEADERS += $$PWD/qparsercontext_p.h \
+ $$PWD/qmaintainingreader_p.h \
+ $$PWD/qquerytransformparser_p.h \
+ $$PWD/qtokenizer_p.h \
+ $$PWD/qtokenrevealer_p.h \
+ $$PWD/qtokensource_p.h \
+ $$PWD/qxquerytokenizer_p.h \
+ $$PWD/qxslttokenizer_p.h \
+ $$PWD/qxslttokenlookup_p.h
+
+SOURCES += $$PWD/qquerytransformparser.cpp \
+ $$PWD/qparsercontext.cpp \
+ $$PWD/qtokenrevealer.cpp \
+ $$PWD/qtokensource.cpp \
+ $$PWD/qxquerytokenizer.cpp \
+ $$PWD/qxslttokenizer.cpp \
+ $$PWD/qxslttokenlookup.cpp
diff --git a/src/xmlpatterns/parser/qmaintainingreader.cpp b/src/xmlpatterns/parser/qmaintainingreader.cpp
new file mode 100644
index 0000000..6798099
--- /dev/null
+++ b/src/xmlpatterns/parser/qmaintainingreader.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qcastingplatform_p.h.
+ * If you need includes in this file, put them in CasttingPlatform.h,
+ * outside of the namespace.
+ */
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+MaintainingReader<TokenLookupClass, LookupKey>::MaintainingReader(const typename ElementDescription<TokenLookupClass, LookupKey>::Hash &elementDescriptions,
+ const QSet<typename TokenLookupClass::NodeName> &standardAttributes,
+ const ReportContext::Ptr &context,
+ QIODevice *const queryDevice) : QXmlStreamReader(queryDevice)
+ , m_hasHandledStandardAttributes(false)
+ , m_context(context)
+ , m_elementDescriptions(elementDescriptions)
+ , m_standardAttributes(standardAttributes)
+{
+ Q_ASSERT(m_context);
+ Q_ASSERT(!m_elementDescriptions.isEmpty());
+
+ /* We start with stripping. */
+ m_stripWhitespace.push(true);
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+MaintainingReader<TokenLookupClass, LookupKey>::~MaintainingReader()
+{
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+QSourceLocation MaintainingReader<TokenLookupClass, LookupKey>::currentLocation() const
+{
+ return QSourceLocation(documentURI(),
+ lineNumber(),
+ columnNumber());
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+QXmlStreamReader::TokenType MaintainingReader<TokenLookupClass, LookupKey>::readNext()
+{
+ const TokenType retval = QXmlStreamReader::readNext();
+
+ switch(retval)
+ {
+ case StartElement:
+ {
+ m_currentElementName = TokenLookupClass::toToken(name());
+ m_currentAttributes = attributes();
+ m_hasHandledStandardAttributes = false;
+
+ if(!m_currentAttributes.hasAttribute(QLatin1String("xml:space")))
+ m_stripWhitespace.push(m_stripWhitespace.top());
+ break;
+ }
+ case EndElement:
+ m_currentElementName = TokenLookupClass::toToken(name());
+ m_stripWhitespace.pop();
+ break;
+ default:
+ break;
+ }
+
+ return retval;
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+bool MaintainingReader<TokenLookupClass, LookupKey>::isWhitespace() const
+{
+ return QXmlStreamReader::isWhitespace()
+ || XPathHelper::isWhitespaceOnly(text());
+}
+
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+void MaintainingReader<TokenLookupClass, LookupKey>::error(const QString &message,
+ const ReportContext::ErrorCode code) const
+{
+ m_context->error(message, code, currentLocation());
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+void MaintainingReader<TokenLookupClass, LookupKey>::warning(const QString &message) const
+{
+ m_context->warning(message, currentLocation());
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+typename TokenLookupClass::NodeName MaintainingReader<TokenLookupClass, LookupKey>::currentElementName() const
+{
+ return m_currentElementName;
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+void MaintainingReader<TokenLookupClass, LookupKey>::validateElement(const LookupKey elementName) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ if(m_elementDescriptions.contains(elementName))
+ {
+ // QHash::value breaks in Metrowerks Compiler
+ const ElementDescription<TokenLookupClass, LookupKey> &desc = *m_elementDescriptions.find(elementName);
+ const int attCount = m_currentAttributes.count();
+
+ QSet<typename TokenLookupClass::NodeName> encounteredXSLTAtts;
+
+ for(int i = 0; i < attCount; ++i)
+ {
+ const QXmlStreamAttribute &attr = m_currentAttributes.at(i);
+ if(attr.namespaceUri().isEmpty())
+ {
+ const typename TokenLookupClass::NodeName attrName(TokenLookupClass::toToken(attr.name()));
+ encounteredXSLTAtts.insert(attrName);
+
+ if(!desc.requiredAttributes.contains(attrName) &&
+ !desc.optionalAttributes.contains(attrName) &&
+ !m_standardAttributes.contains(attrName) &&
+ !isAnyAttributeAllowed())
+ {
+ QString translationString;
+
+ QList<typename TokenLookupClass::NodeName> all(desc.requiredAttributes.toList() + desc.optionalAttributes.toList());
+ const int totalCount = all.count();
+ QStringList allowed;
+
+ for(int i = 0; i < totalCount; ++i)
+ allowed.append(QPatternist::formatKeyword(TokenLookupClass::toString(all.at(i))));
+
+ /* Note, we can't run toString() on attrName, because we're in this branch,
+ * the token lookup doesn't have the string(!).*/
+ const QString stringedName(attr.name().toString());
+
+ if(totalCount == 0)
+ {
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only the standard attributes can appear.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()));
+ }
+ else if(totalCount == 1)
+ {
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()),
+ allowed.first());
+ }
+ else if(totalCount == 1)
+ {
+ /* Note, allowed has already had formatKeyword() applied. */
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()),
+ allowed.first(),
+ allowed.last());
+ }
+ else
+ {
+ /* Note, allowed has already had formatKeyword() applied. */
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()),
+ allowed.join(QLatin1String(", ")));
+ }
+
+ m_context->error(translationString,
+ ReportContext::XTSE0090,
+ currentLocation());
+ }
+ }
+ else if(attr.namespaceUri() == namespaceUri())
+ {
+ m_context->error(QtXmlPatterns::tr("XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is.")
+ .arg(formatKeyword(attr.name())),
+ ReportContext::XTSE0090,
+ currentLocation());
+ }
+ /* Else, attributes in other namespaces are allowed, continue. */
+ }
+
+ const QSet<typename TokenLookupClass::NodeName> requiredButMissing(QSet<typename TokenLookupClass::NodeName>(desc.requiredAttributes).subtract(encounteredXSLTAtts));
+
+ if(!requiredButMissing.isEmpty())
+ {
+ error(QtXmlPatterns::tr("The attribute %1 must appear on element %2.")
+ .arg(QPatternist::formatKeyword(TokenLookupClass::toString(*requiredButMissing.constBegin())),
+ formatKeyword(name())),
+ ReportContext::XTSE0010);
+ }
+ }
+ else
+ {
+ error(QtXmlPatterns::tr("The element with local name %1 does not exist in XSL-T.").arg(formatKeyword(name())),
+ ReportContext::XTSE0010);
+ }
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+bool MaintainingReader<TokenLookupClass, LookupKey>::hasAttribute(const QString &namespaceURI,
+ const QString &localName) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ return m_currentAttributes.hasAttribute(namespaceURI, localName);
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+bool MaintainingReader<TokenLookupClass, LookupKey>::hasAttribute(const QString &localName) const
+{
+ return hasAttribute(QString(), localName);
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+QString MaintainingReader<TokenLookupClass, LookupKey>::readAttribute(const QString &localName,
+ const QString &namespaceURI) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ Q_ASSERT_X(m_currentAttributes.hasAttribute(namespaceURI, localName),
+ Q_FUNC_INFO,
+ "Validation must be done before this function is called.");
+
+ return m_currentAttributes.value(namespaceURI, localName).toString();
+}
+
diff --git a/src/xmlpatterns/parser/qmaintainingreader_p.h b/src/xmlpatterns/parser/qmaintainingreader_p.h
new file mode 100644
index 0000000..e1610bf
--- /dev/null
+++ b/src/xmlpatterns/parser/qmaintainingreader_p.h
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_MaintainingReader_H
+#define Patternist_MaintainingReader_H
+
+#include <QSet>
+#include <QSourceLocation>
+#include <QStack>
+#include <QStringList>
+#include <QXmlStreamReader>
+
+#include "qxpathhelper_p.h"
+#include "qxslttokenlookup_p.h"
+
+class QUrl;
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A structure that lists the optional and required
+ * attributes of an element. Used with MaintainingReader.
+ *
+ * A constant source to misunderstandings is mixing up the order of
+ * arguments for functions that takes a local name and a namespace. Be wary
+ * of this.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @since 4.5
+ */
+ template<typename TokenLookupClass,
+ typename LookupKey = typename TokenLookupClass::NodeName>
+ class ElementDescription
+ {
+ public:
+ typedef QHash<LookupKey, ElementDescription<TokenLookupClass, LookupKey> > Hash;
+ QSet<typename TokenLookupClass::NodeName> requiredAttributes;
+ QSet<typename TokenLookupClass::NodeName> optionalAttributes;
+ };
+
+ /**
+ * @short Base class for tokenizers that reads XML formats. This is
+ * XSLTTokenizer, and the W3C XML Schema parser.
+ *
+ * MaintainingReader is intended for sub-classing.
+ *
+ * @tparam TokenLookupClass The name of the class that is generated by
+ * QTokenAutomaton and which supplies tokenizing tokens. For XSLTTokenizer,
+ * this is XSLTTokenLookup, for instance.
+ *
+ * @tparam LookupKey The type that is passed to validateElement() and is
+ * the key in ElementDescription. For the schema code, where elements have
+ * different interpretations depending on context, the lookup key is hence
+ * not equal element name.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @since 4.5
+ */
+ template<typename TokenLookupClass,
+ typename LookupKey = typename TokenLookupClass::NodeName>
+ class MaintainingReader : public QXmlStreamReader
+ , protected TokenLookupClass
+ {
+ protected:
+
+ MaintainingReader(const typename ElementDescription<TokenLookupClass, LookupKey>::Hash &elementDescriptions,
+ const QSet<typename TokenLookupClass::NodeName> &standardAttributes,
+ const ReportContext::Ptr &context,
+ QIODevice *const queryDevice);
+
+ virtual ~MaintainingReader();
+
+ TokenType readNext();
+
+ /**
+ * Returns the name of the current element.
+ */
+ inline typename TokenLookupClass::NodeName currentElementName() const;
+
+ /**
+ * @short Convenience function for calling ReportContext::error().
+ */
+ void error(const QString &message,
+ const ReportContext::ErrorCode code) const;
+
+ /**
+ * @short Convenience function for calling ReportContext::warning().
+ */
+ void warning(const QString &message) const;
+
+ /**
+ * @short Returns the location of the document that MaintainingReader
+ * is parsing. Used for error reporting
+ */
+ virtual QUrl documentURI() const = 0;
+
+ /**
+ * @short Returns @c true, if any attribute is allowed on the
+ * element currently being validated.
+ */
+ virtual bool isAnyAttributeAllowed() const = 0;
+
+ /**
+ * QXmlStreamReader::isWhitespace() returns true for whitespace that is
+ * not expressed as character references, while XSL-T operatates ontop
+ * of the XDM, which means we needs to return true for those too.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#data-model">4 Data Model</a>
+ */
+ bool isWhitespace() const;
+
+ /**
+ * This function is not merged with handleStandardAttributes() because
+ * handleStandardAttributes() needs to be called for all elements,
+ * while validateElement() only applies to XSL-T elements.
+ *
+ * @see handleStandardAttributes()
+ */
+ void validateElement(const LookupKey name) const;
+
+ QXmlStreamAttributes m_currentAttributes;
+
+ bool m_hasHandledStandardAttributes;
+
+ /**
+ * This stack mirrors the depth of elements in the parsed document. If
+ * no @c xml:space is present on the current element, MaintainingReader
+ * simply pushes the current top(). However, it never sets the value
+ * depending on @c xml:space's value.
+ */
+ QStack<bool> m_stripWhitespace;
+
+ /**
+ * @short Returns the value for attribute by name \a name.
+ *
+ * If it doesn't exist, an error is raised.
+ *
+ * It is assumed that m_reader's current state is
+ * QXmlStreamReader::StartElement.
+ */
+ QString readAttribute(const QString &localName,
+ const QString &namespaceURI = QString()) const;
+
+ /**
+ * @short Returns @c true if the current element has an attribute whose
+ * name is @p namespaceURI and local name is @p localName.
+ */
+ bool hasAttribute(const QString &namespaceURI, const QString &localName) const;
+
+ /**
+ * @short Returns @c true if the current element has an attribute whose
+ * local name is @p localName and namespace URI is null.
+ */
+ inline bool hasAttribute(const QString &localName) const;
+
+ private:
+ typename TokenLookupClass::NodeName m_currentElementName;
+
+ /**
+ * This member is private, see the error() and warning() functions in
+ * this class.
+ */
+ const ReportContext::Ptr m_context;
+
+ /**
+ * Returns the current location that QXmlStreamReader has.
+ */
+ inline QSourceLocation currentLocation() const;
+
+ const typename ElementDescription<TokenLookupClass, LookupKey>::Hash m_elementDescriptions;
+ const QSet<typename TokenLookupClass::NodeName> m_standardAttributes;
+ Q_DISABLE_COPY(MaintainingReader)
+ };
+
+#include "qmaintainingreader.cpp"
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/parser/qparsercontext.cpp b/src/xmlpatterns/parser/qparsercontext.cpp
new file mode 100644
index 0000000..22e6221
--- /dev/null
+++ b/src/xmlpatterns/parser/qparsercontext.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGlobal>
+
+#include "qexpression_p.h"
+#include "qstaticcontext_p.h"
+#include "qtokenizer_p.h"
+
+#include "qparsercontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ParserContext::ParserContext(const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ Tokenizer *const tokener) : staticContext(context)
+ , tokenizer(tokener)
+ , languageAccent(lang)
+ , nodeTestSource(BuiltinTypes::element)
+ , moduleNamespace(StandardNamespaces::empty)
+ , isPreviousEnclosedExpr(false)
+ , elementConstructorDepth(0)
+ , hasSecondPrologPart(false)
+ , preserveNamespacesMode(true)
+ , inheritNamespacesMode(true)
+ , isParsingPattern(false)
+ , currentImportPrecedence(1)
+ , m_evaluationCacheSlot(-1)
+ , m_expressionSlot(0)
+ , m_positionSlot(-1)
+ , m_globalVariableSlot(-1)
+ , m_currentTemplateID(InitialTemplateID)
+{
+ resolvers.push(context->namespaceBindings());
+ Q_ASSERT(tokenizer);
+ Q_ASSERT(context);
+ m_isParsingWithParam.push(false);
+ isBackwardsCompat.push(false);
+}
+
+void ParserContext::finalizePushedVariable(const int amount,
+ const bool shouldPop)
+{
+ for(int i = 0; i < amount; ++i)
+ {
+ const VariableDeclaration::Ptr var(shouldPop ? variables.pop() : variables.top());
+ Q_ASSERT(var);
+
+ if(var->isUsed())
+ continue;
+ else
+ {
+ staticContext->warning(QtXmlPatterns::tr("The variable %1 is unused")
+ .arg(formatKeyword(var, staticContext->namePool())));
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/parser/qparsercontext_p.h b/src/xmlpatterns/parser/qparsercontext_p.h
new file mode 100644
index 0000000..6319db7
--- /dev/null
+++ b/src/xmlpatterns/parser/qparsercontext_p.h
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ParserContext_H
+#define Patternist_ParserContext_H
+
+#include <QFlags>
+#include <QSharedData>
+#include <QStack>
+#include <QStringList>
+#include <QtGlobal>
+#include <QXmlQuery>
+
+#include "qbuiltintypes_p.h"
+#include "qfunctionsignature_p.h"
+#include "qorderby_p.h"
+#include "qtemplatemode_p.h"
+#include "quserfunctioncallsite_p.h"
+#include "quserfunction_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class Tokenizer;
+
+ /**
+ * @short Contains data used when parsing and tokenizing.
+ *
+ * When ExpressionFactory::create() is called, an instance of this class
+ * is passed to the scanner and parser. It holds all information that is
+ * needed to create the expression.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ParserContext : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ParserContext> Ptr;
+
+ enum PrologDeclaration
+ {
+ BoundarySpaceDecl = 1,
+ DefaultCollationDecl = 2,
+ BaseURIDecl = 4,
+ ConstructionDecl = 8,
+ OrderingModeDecl = 16,
+ EmptyOrderDecl = 32,
+ CopyNamespacesDecl = 64,
+ DeclareDefaultElementNamespace = 128,
+ DeclareDefaultFunctionNamespace = 256
+ };
+
+ typedef QFlags<PrologDeclaration> PrologDeclarations;
+
+ /**
+ * Constructs a ParserContext instance.
+ *
+ * @param context the static context as defined in XPath. This contain
+ * namespace bindings, error handler, and other information necessary
+ * for creating an XPath expression.
+ * @param lang the particular XPath language sub-set that should be parsed
+ * @param tokenizer the Tokenizer to use.
+ * @see ExpressionFactory::LanguageAccent
+ */
+ ParserContext(const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ Tokenizer *const tokenizer);
+
+ /**
+ * @short Removes the recently pushed variables from
+ * scope. The amount of removed variables is @p amount.
+ *
+ * finalizePushedVariable() can be seen as popping the variable.
+ *
+ */
+ void finalizePushedVariable(const int amount = 1,
+ const bool shouldPop = true);
+
+ inline VariableSlotID allocatePositionalSlot()
+ {
+ ++m_positionSlot;
+ return m_positionSlot;
+ }
+
+ inline VariableSlotID allocateExpressionSlot()
+ {
+ const VariableSlotID retval = m_expressionSlot;
+ ++m_expressionSlot;
+ return retval;
+ }
+
+ inline VariableSlotID allocateGlobalVariableSlot()
+ {
+ ++m_globalVariableSlot;
+ return m_globalVariableSlot;
+ }
+
+ inline bool hasDeclaration(const PrologDeclaration decl) const
+ {
+ return m_prologDeclarations.testFlag(decl);
+ }
+
+ inline void registerDeclaration(const PrologDeclaration decl)
+ {
+ m_prologDeclarations |= decl;
+ }
+
+ /**
+ * The namespaces declared with <tt>declare namespace</tt>.
+ */
+ QStringList declaredPrefixes;
+
+ /**
+ * This is a temporary stack, used for keeping variables in scope,
+ * such as for function arguments & let clauses.
+ */
+ VariableDeclaration::Stack variables;
+
+ inline bool isXSLT() const
+ {
+ return languageAccent == QXmlQuery::XSLT20;
+ }
+
+ const StaticContext::Ptr staticContext;
+ /**
+ * We don't store a Tokenizer::Ptr here, because then we would get a
+ * circular referencing between ParserContext and XSLTTokenizer, and
+ * hence they would never destruct.
+ */
+ Tokenizer *const tokenizer;
+ const QXmlQuery::QueryLanguage languageAccent;
+
+ /**
+ * Only used in the case of XSL-T. Is the name of the initial template
+ * to call. If null, no name was provided, and regular template
+ * matching should be done.
+ */
+ QXmlName initialTemplateName;
+
+ /**
+ * Used when parsing direct element constructors. It is used
+ * for ensuring tags are well-balanced.
+ */
+ QStack<QXmlName> tagStack;
+
+ /**
+ * The actual expression, the Query. This member may be @c null,
+ * such as in the case of an XQuery library module.
+ */
+ Expression::Ptr queryBody;
+
+ /**
+ * The user functions declared in the prolog.
+ */
+ UserFunction::List userFunctions;
+
+ /**
+ * Contains all calls to user defined functions.
+ */
+ UserFunctionCallsite::List userFunctionCallsites;
+
+ /**
+ * All variables declared with <tt>declare variable</tt>.
+ */
+ VariableDeclaration::List declaredVariables;
+
+ inline VariableSlotID currentPositionSlot() const
+ {
+ return m_positionSlot;
+ }
+
+ inline VariableSlotID currentExpressionSlot() const
+ {
+ return m_expressionSlot;
+ }
+
+ inline void restoreNodeTestSource()
+ {
+ nodeTestSource = BuiltinTypes::element;
+ }
+
+ inline VariableSlotID allocateCacheSlot()
+ {
+ return ++m_evaluationCacheSlot;
+ }
+
+ inline VariableSlotID allocateCacheSlots(const int count)
+ {
+ const VariableSlotID retval = m_evaluationCacheSlot + 1;
+ m_evaluationCacheSlot += count + 1;
+ return retval;
+ }
+
+ ItemType::Ptr nodeTestSource;
+
+ QStack<Expression::Ptr> typeswitchSource;
+
+ /**
+ * The library module namespace set with <tt>declare module</tt>.
+ */
+ QXmlName::NamespaceCode moduleNamespace;
+
+ /**
+ * When a direct element constructor is processed, resolvers are
+ * created in order to carry the namespace declarations. In such case,
+ * the old resolver is pushed here.
+ */
+ QStack<NamespaceResolver::Ptr> resolvers;
+
+ /**
+ * This is used for handling the following obscene case:
+ *
+ * - <tt>\<e\>{1}{1}\<\/e\></tt> produce <tt>\<e\>11\</e\></tt>
+ * - <tt>\<e\>{1, 1}\<\/e\></tt> produce <tt>\<e\>1 1\</e\></tt>
+ *
+ * This boolean tracks whether the previous reduction inside element
+ * content was done with an enclosed expression.
+ */
+ bool isPreviousEnclosedExpr;
+
+ int elementConstructorDepth;
+
+ QStack<bool> scanOnlyStack;
+
+ QStack<OrderBy::Stability> orderStability;
+
+ /**
+ * Whether any prolog declaration that must occur after the first
+ * group has been encountered.
+ */
+ bool hasSecondPrologPart;
+
+ bool preserveNamespacesMode;
+ bool inheritNamespacesMode;
+
+ /**
+ * Contains all named templates. Since named templates
+ * can also have rules, each body may also be in templateRules.
+ */
+ QHash<QXmlName, Template::Ptr> namedTemplates;
+
+ /**
+ * All the @c xsl:call-template instructions that we have encountered.
+ */
+ QVector<Expression::Ptr> templateCalls;
+
+ /**
+ * If we're in XSL-T, and a variable reference is encountered
+ * which isn't in-scope, it's added to this hash since a global
+ * variable declaration may appear later on.
+ *
+ * We use a multi hash, since we can encounter several references to
+ * the same variable before it's declared.
+ */
+ QMultiHash<QXmlName, Expression::Ptr> unresolvedVariableReferences;
+
+ /**
+ *
+ * Contains the encountered template rules, as opposed
+ * to named templates.
+ *
+ * The key is the name of the template mode. If it's a default
+ * constructed value, it's the default mode.
+ *
+ * Since templates rules may also be named, each body may also be in
+ * namedTemplates.
+ *
+ * To be specific, the values are not the templates, the values are
+ * modes, and the TemplateMode contains the patterns and bodies.
+ */
+ QHash<QXmlName, TemplateMode::Ptr> templateRules;
+
+ /**
+ * @short Returns the TemplateMode for @p modeName or @c null if the
+ * mode being asked for is @c #current.
+ */
+ TemplateMode::Ptr modeFor(const QXmlName &modeName)
+ {
+ /* #current is not a mode, so it cannot contain templates. #current
+ * specifies how to look up templates wrt. mode. This check helps
+ * code that calls us, asking for the mode it needs to lookup in.
+ */
+ if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current))
+ return TemplateMode::Ptr();
+
+ TemplateMode::Ptr &mode = templateRules[modeName];
+
+ if(!mode)
+ mode = TemplateMode::Ptr(new TemplateMode(modeName));
+
+ Q_ASSERT(templateRules[modeName]);
+ return mode;
+ }
+
+ inline TemplatePattern::ID allocateTemplateID()
+ {
+ ++m_currentTemplateID;
+ return m_currentTemplateID;
+ }
+
+ /**
+ * The @c xsl:param appearing inside template.
+ */
+ VariableDeclaration::List templateParameters;
+
+ /**
+ * The @c xsl:with-param appearing in template calling instruction.
+ */
+ WithParam::Hash templateWithParams;
+
+ inline void templateParametersHandled()
+ {
+ finalizePushedVariable(templateParameters.count());
+ templateParameters.clear();
+ }
+
+ inline void templateWithParametersHandled()
+ {
+ templateWithParams.clear();
+ }
+
+ inline bool isParsingWithParam() const
+ {
+ return m_isParsingWithParam.top();
+ }
+
+ void startParsingWithParam()
+ {
+ m_isParsingWithParam.push(true);
+ }
+
+ void endParsingWithParam()
+ {
+ m_isParsingWithParam.pop();
+ }
+
+ /**
+ * This is used to deal with XSL-T's exception to the @c node() type,
+ * which doesn't match document nodes.
+ */
+ bool isParsingPattern;
+
+ ImportPrecedence currentImportPrecedence;
+
+ bool isFirstTemplate() const
+ {
+ return m_currentTemplateID == InitialTemplateID;
+ }
+
+ /**
+ * Whether we're processing XSL-T 1.0 code.
+ */
+ QStack<bool> isBackwardsCompat;
+
+ private:
+ enum
+ {
+ InitialTemplateID = -1
+ };
+
+ VariableSlotID m_evaluationCacheSlot;
+ VariableSlotID m_expressionSlot;
+ VariableSlotID m_positionSlot;
+ PrologDeclarations m_prologDeclarations;
+ VariableSlotID m_globalVariableSlot;
+ TemplatePattern::ID m_currentTemplateID;
+
+ /**
+ * The default is @c false. If we're not parsing @c xsl:with-param,
+ * hence parsing @c xsl:param, the value has changed.
+ */
+ QStack<bool> m_isParsingWithParam;
+ Q_DISABLE_COPY(ParserContext)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/qquerytransformparser.cpp b/src/xmlpatterns/parser/qquerytransformparser.cpp
new file mode 100644
index 0000000..4858e11
--- /dev/null
+++ b/src/xmlpatterns/parser/qquerytransformparser.cpp
@@ -0,0 +1,8035 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* A Bison parser, made by GNU Bison 2.3a. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.3a"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+/* Substitute the variable and function names. */
+#define yyparse XPathparse
+#define yylex XPathlex
+#define yyerror XPatherror
+#define yylval XPathlval
+#define yychar XPathchar
+#define yydebug XPathdebug
+#define yynerrs XPathnerrs
+#define yylloc XPathlloc
+
+/* Copy the first part of user declarations. */
+/* Line 164 of yacc.c. */
+#line 22 "querytransformparser.ypp"
+
+#include <limits>
+
+#include <QUrl>
+
+#include "qabstractfloat_p.h"
+#include "qandexpression_p.h"
+#include "qanyuri_p.h"
+#include "qapplytemplate_p.h"
+#include "qargumentreference_p.h"
+#include "qarithmeticexpression_p.h"
+#include "qatomicstring_p.h"
+#include "qattributeconstructor_p.h"
+#include "qattributenamevalidator_p.h"
+#include "qaxisstep_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcalltemplate_p.h"
+#include "qcastableas_p.h"
+#include "qcastas_p.h"
+#include "qcombinenodes_p.h"
+#include "qcommentconstructor_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qcomputednamespaceconstructor_p.h"
+#include "qcontextitem_p.h"
+#include "qcopyof_p.h"
+#include "qcurrentitemstore_p.h"
+#include "qdebug_p.h"
+#include "qdelegatingnamespaceresolver_p.h"
+#include "qdocumentconstructor_p.h"
+#include "qelementconstructor_p.h"
+#include "qemptysequence_p.h"
+#include "qemptysequencetype_p.h"
+#include "qevaluationcache_p.h"
+#include "qexpressionfactory_p.h"
+#include "qexpressionsequence_p.h"
+#include "qexpressionvariablereference_p.h"
+#include "qexternalvariablereference_p.h"
+#include "qforclause_p.h"
+#include "qfunctioncall_p.h"
+#include "qfunctionfactory_p.h"
+#include "qfunctionsignature_p.h"
+#include "qgeneralcomparison_p.h"
+#include "qgenericpredicate_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qifthenclause_p.h"
+#include "qinstanceof_p.h"
+#include "qletclause_p.h"
+#include "qliteral_p.h"
+#include "qlocalnametest_p.h"
+#include "qnamespaceconstructor_p.h"
+#include "qnamespacenametest_p.h"
+#include "qncnameconstructor_p.h"
+#include "qnodecomparison_p.h"
+#include "qnodesort_p.h"
+#include "qorderby_p.h"
+#include "qorexpression_p.h"
+#include "qparsercontext_p.h"
+#include "qpath_p.h"
+#include "qpatternistlocale_p.h"
+#include "qpositionalvariablereference_p.h"
+#include "qprocessinginstructionconstructor_p.h"
+#include "qqnameconstructor_p.h"
+#include "qqnametest_p.h"
+#include "qqnamevalue_p.h"
+#include "qquantifiedexpression_p.h"
+#include "qrangeexpression_p.h"
+#include "qrangevariablereference_p.h"
+#include "qreturnorderby_p.h"
+#include "qschemanumeric_p.h"
+#include "qschematypefactory_p.h"
+#include "qsimplecontentconstructor_p.h"
+#include "qstaticbaseuristore_p.h"
+#include "qstaticcompatibilitystore_p.h"
+#include "qtemplateparameterreference_p.h"
+#include "qtemplate_p.h"
+#include "qtextnodeconstructor_p.h"
+#include "qtokenizer_p.h"
+#include "qtreatas_p.h"
+#include "qtypechecker_p.h"
+#include "qunaryexpression_p.h"
+#include "qunresolvedvariablereference_p.h"
+#include "quserfunctioncallsite_p.h"
+#include "qvaluecomparison_p.h"
+#include "qxpathhelper_p.h"
+#include "qxsltsimplecontentconstructor_p.h"
+
+/*
+ * The cpp generated with bison 2.1 wants to
+ * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
+ */
+#define YYMALLOC malloc
+#define YYFREE free
+
+QT_BEGIN_NAMESPACE
+
+/* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
+ * undocumented reason. */
+namespace QPatternist
+{
+
+/**
+ * "Macro that you define with #define in the Bison declarations
+ * section to request verbose, specific error message strings when
+ * yyerror is called."
+ */
+#define YYERROR_VERBOSE 1
+
+#undef YYLTYPE_IS_TRIVIAL
+#define YYLTYPE_IS_TRIVIAL 0
+
+/* Suppresses `warning: "YYENABLE_NLS" is not defined`
+ * @c YYENABLE_NLS enables Bison internationalization, and we don't
+ * use that, so disable it. See the Bison Manual, section 4.5 Parser Internationalization.
+ */
+#define YYENABLE_NLS 0
+
+static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return QSourceLocation(parseInfo->tokenizer->queryURI(),
+ sourceLocator.first_line,
+ sourceLocator.first_column);
+}
+
+/**
+ * @internal
+ * @relates QXmlQuery
+ */
+typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;
+
+/**
+ * @short Flags invalid expressions and declarations in the currently
+ * parsed language.
+ *
+ * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and
+ * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's
+ * identity constraints, it is the union of all the constructs in these
+ * languages. However, when dealing with each language individually, we
+ * regularly need to disallow some expressions, such as direct element
+ * constructors when parsing XSL-T, or the typeswitch when parsing XPath.
+ *
+ * This is further complicated by that XSLTTokenizer sometimes generates code
+ * which is allowed in XQuery but not in XPath. For that reason the token
+ * INTERNAL is sometimes generated, which signals that an expression, for
+ * instance the @c let clause, should not be flagged as an error, because it's
+ * used for internal purposes.
+ *
+ * Hence, this function is called from each expression and declaration with @p
+ * allowedLanguages stating what languages it is allowed in.
+ *
+ * If @p isInternal is @c true, no error is raised. Otherwise, if the current
+ * language is not in @p allowedLanguages, an error is raised.
+ */
+static void allowedIn(const QueryLanguages allowedLanguages,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const bool isInternal = false)
+{
+ /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed
+ * and XSL-T is the language, it's ok. */
+ if(!isInternal &&
+ (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
+ {
+
+ QString langName;
+
+ switch(parseInfo->languageAccent)
+ {
+ case QXmlQuery::XPath20:
+ langName = QLatin1String("XPath 2.0");
+ break;
+ case QXmlQuery::XSLT20:
+ langName = QLatin1String("XSL-T 2.0");
+ break;
+ case QXmlQuery::XQuery10:
+ langName = QLatin1String("XQuery 1.0");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintSelector:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintField:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
+ break;
+ }
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered "
+ "which is disallowed in the current language(%1).").arg(langName),
+ ReportContext::XPST0003,
+ fromYYLTYPE(sourceLocator, parseInfo));
+
+ }
+}
+
+static inline bool isVariableReference(const Expression::ID id)
+{
+ return id == Expression::IDExpressionVariableReference
+ || id == Expression::IDRangeVariableReference
+ || id == Expression::IDArgumentReference;
+}
+
+class ReflectYYLTYPE : public SourceLocationReflection
+{
+public:
+ inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const pi) : m_sl(sourceLocator)
+ , m_parseInfo(pi)
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const
+ {
+ return this;
+ }
+
+ virtual QSourceLocation sourceLocation() const
+ {
+ return fromYYLTYPE(m_sl, m_parseInfo);
+ }
+
+ virtual QString description() const
+ {
+ Q_ASSERT(false);
+ return QString();
+ }
+
+private:
+ const YYLTYPE &m_sl;
+ const ParserContext *const m_parseInfo;
+};
+
+/**
+ * @short Centralizes a translation string for the purpose of increasing consistency.
+ */
+static inline QString unknownType()
+{
+ return QtXmlPatterns::tr("%1 is an unknown schema type.");
+}
+
+static inline Expression::Ptr create(Expression *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Expression::Ptr(expr);
+}
+
+static inline Template::Ptr create(Template *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Template::Ptr(expr);
+}
+
+static inline Expression::Ptr create(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
+ return expr;
+}
+
+static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
+ sourceLocator,
+ parseInfo);
+}
+
+static void loadPattern(const Expression::Ptr &matchPattern,
+ TemplatePattern::Vector &ourPatterns,
+ const TemplatePattern::ID id,
+ const PatternPriority priority,
+ const Template::Ptr &temp)
+{
+ Q_ASSERT(temp);
+
+ const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;
+
+ ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
+}
+
+static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
+ const SequenceType::Ptr &reqType,
+ const ParserContext *const parseInfo)
+{
+ return TypeChecker::applyFunctionConversion(body, reqType,
+ parseInfo->staticContext,
+ ReportContext::XTTE0505,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert | TypeChecker::GeneratePromotion));
+}
+
+static void registerNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &body,
+ ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const Template::Ptr &temp)
+{
+ Template::Ptr &e = parseInfo->namedTemplates[name];
+
+ if(e)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A template with name %1 "
+ "has already been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(),
+ name)),
+ ReportContext::XTSE0660,
+ fromYYLTYPE(sourceLocator, parseInfo));
+ }
+ else
+ {
+ e = temp;
+ e->body = body;
+ }
+}
+
+/**
+ * @short Centralizes code for creating numeric literals.
+ */
+template<typename TNumberClass>
+Expression::Ptr createNumericLiteral(const QString &in,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Item num(TNumberClass::fromLexical(in));
+
+ if(num.template as<AtomicValue>()->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid numeric literal.")
+ .arg(formatData(in)),
+ ReportContext::XPST0003, fromYYLTYPE(sl, parseInfo));
+ return Expression::Ptr(); /* Avoid compiler warning. */
+ }
+ else
+ return create(new Literal(num), sl, parseInfo);
+}
+
+/**
+ * @short The generated Bison parser calls this function when there is a parse error.
+ *
+ * It is not called, nor should be, for logical errors(which the Bison not know about). For those,
+ * ReportContext::error() is called.
+ */
+static int XPatherror(YYLTYPE *sourceLocator, const ParserContext *const parseInfo, const char *const msg)
+{
+ Q_UNUSED(sourceLocator);
+ Q_ASSERT(parseInfo);
+
+ parseInfo->staticContext->error(escape(QLatin1String(msg)), ReportContext::XPST0003, fromYYLTYPE(*sourceLocator, parseInfo));
+ return 1;
+}
+
+/**
+ * When we want to connect the OrderBy and ReturnOrderBy, it might be that we have other expressions, such
+ * as @c where and @c let inbetween. We need to continue through them. This function does that.
+ */
+static ReturnOrderBy *locateReturnClause(const Expression::Ptr &expr)
+{
+ Q_ASSERT(expr);
+
+ const Expression::ID id = expr->id();
+ if(id == Expression::IDLetClause || id == Expression::IDIfThenClause || id == Expression::IDForClause)
+ return locateReturnClause(expr->operands()[1]);
+ else if(id == Expression::IDReturnOrderBy)
+ return expr->as<ReturnOrderBy>();
+ else
+ return 0;
+}
+
+static inline bool isPredicate(const Expression::ID id)
+{
+ return id == Expression::IDGenericPredicate ||
+ id == Expression::IDFirstItemPredicate;
+}
+
+/**
+ * Assumes expr is an AxisStep wrapped in some kind of predicates or paths. Filters
+ * through the predicates and returns the AxisStep.
+ */
+static Expression::Ptr findAxisStep(const Expression::Ptr &expr,
+ const bool throughStructures = true)
+{
+ Q_ASSERT(expr);
+
+ if(!throughStructures)
+ return expr;
+
+ Expression *candidate = expr.data();
+ Expression::ID id = candidate->id();
+
+ while(isPredicate(id) || id == Expression::IDPath)
+ {
+ const Expression::List &children = candidate->operands();
+ if(children.isEmpty())
+ return Expression::Ptr();
+ else
+ {
+ candidate = children.first().data();
+ id = candidate->id();
+ }
+ }
+
+ if(id == Expression::IDEmptySequence)
+ return Expression::Ptr();
+ else
+ {
+ Q_ASSERT(candidate->is(Expression::IDAxisStep));
+ return Expression::Ptr(candidate);
+ }
+}
+
+static void changeToTopAxis(const Expression::Ptr &op)
+{
+ /* This axis must have been written away by now. */
+ Q_ASSERT(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisChild);
+
+ if(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisSelf)
+ op->as<AxisStep>()->setAxis(QXmlNodeModelIndex::AxisAttributeOrTop);
+}
+
+/**
+ * @short Writes @p operand1 and @p operand2, two operands in an XSL-T pattern,
+ * into an equivalent XPath expression.
+ *
+ * Essentially, the following rewrite is done:
+ *
+ * <tt>
+ * axis1::test1(a)/axis2::test2(b)
+ * =>
+ * child-or-top::test2(b)[parent::test1(a)]
+ * </tt>
+ *
+ * Section 5.5.3 The Meaning of a Pattern talks about rewrites that are applied to
+ * only the first step in a pattern, but since we're doing rewrites more radically,
+ * its line of reasoning cannot be followed.
+ *
+ * Keep in mind the rewrites that non-terminal PatternStep do.
+ *
+ * @see createIdPatternPath()
+ */
+static inline Expression::Ptr createPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandL(findAxisStep(operand1, false));
+
+ if(operandL->is(Expression::IDAxisStep))
+ operandL->as<AxisStep>()->setAxis(axis);
+ else
+ findAxisStep(operand1)->as<AxisStep>()->setAxis(axis);
+
+ return create(GenericPredicate::create(operand2, operandL,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Performs the same role as createPatternPath(), but is tailored
+ * for @c fn:key() and @c fn:id().
+ *
+ * @c fn:key() and @c fn:id() can be part of path patterns(only as the first step,
+ * to be precise) and that poses a challenge to rewriting because what
+ * createPatternPath() is not possible to express, since the functions cannot be
+ * node tests. E.g, this rewrite is not possible:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::id-or-key]
+ * </tt>
+ *
+ * Our approach is to rewrite like this:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::node is id-or-key]
+ * </tt>
+ *
+ * @p operand1 is the call to @c fn:key() or @c fn:id(), @p operand2
+ * the right operand, and @p axis the target axis to rewrite to.
+ *
+ * @see createPatternPath()
+ */
+static inline Expression::Ptr createIdPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandR(findAxisStep(operand2));
+ Q_ASSERT(operandR);
+ changeToTopAxis(operandR);
+
+ const Expression::Ptr parentStep(create(new AxisStep(axis, BuiltinTypes::node),
+ sl,
+ parseInfo));
+ const Expression::Ptr isComp(create(new NodeComparison(parentStep,
+ QXmlNodeModelIndex::Is,
+ operand1),
+ sl,
+ parseInfo));
+
+ return create(GenericPredicate::create(operandR, isComp,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Centralizes a translation message, for the
+ * purpose of consistency and modularization.
+ */
+static inline QString prologMessage(const char *const msg)
+{
+ Q_ASSERT(msg);
+ return QtXmlPatterns::tr("Only one %1 declaration can occur in the query prolog.").arg(formatKeyword(msg));
+}
+
+/**
+ * @short Resolves against the static base URI and checks that @p collation
+ * is a supported Unicode Collation.
+ *
+ * "If a default collation declaration specifies a collation by a
+ * relative URI, that relative URI is resolved to an absolute
+ * URI using the base URI in the static context."
+ *
+ * @returns the Unicode Collation properly resolved, if @p collation is a valid collation
+ */
+template<const ReportContext::ErrorCode errorCode>
+static QUrl resolveAndCheckCollation(const QString &collation,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ QUrl uri(AnyURI::toQUrl<ReportContext::XQST0046>(collation, parseInfo->staticContext, &ryy));
+
+ if(uri.isRelative())
+ uri = parseInfo->staticContext->baseURI().resolved(uri);
+
+ XPathHelper::checkCollationSupport<errorCode>(uri.toString(), parseInfo->staticContext, &ryy);
+
+ return uri;
+}
+
+/* The Bison generated parser declares macros that aren't used
+ * so suppress the warnings by fake usage of them.
+ *
+ * We do the same for some more defines in the first action. */
+#if defined(YYLSP_NEEDED) \
+ || defined(YYBISON) \
+ || defined(YYBISON_VERSION) \
+ || defined(YYPURE) \
+ || defined(yydebug) \
+ || defined(YYSKELETON_NAME)
+#endif
+
+/**
+ * Wraps @p operand with a CopyOf in case it makes any difference.
+ *
+ * There is no need to wrap the return value in a call to create(), it's
+ * already done.
+ */
+static Expression::Ptr createCopyOf(const Expression::Ptr &operand,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ return create(new CopyOf(operand, parseInfo->inheritNamespacesMode,
+ parseInfo->preserveNamespacesMode), sl, parseInfo);
+}
+
+static Expression::Ptr createCompatStore(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(new StaticCompatibilityStore(expr), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates an Expression that corresponds to <tt>/</tt>. This is literally
+ * <tt>fn:root(self::node()) treat as document-node()</tt>.
+ */
+static Expression::Ptr createRootExpression(const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::root);
+
+ Expression::List args;
+ args.append(create(new ContextItem(), sl, parseInfo));
+
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ const Expression::Ptr fnRoot(parseInfo->staticContext->functionSignatures()
+ ->createFunctionCall(name, args, parseInfo->staticContext, &ryy));
+ Q_ASSERT(fnRoot);
+
+ return create(new TreatAs(create(fnRoot, sl, parseInfo), CommonSequenceTypes::ExactlyOneDocumentNode), sl, parseInfo);
+}
+
+static int XPathlex(YYSTYPE *lexVal, YYLTYPE *sourceLocator, const ParserContext *const parseInfo)
+{
+#ifdef Patternist_DEBUG_PARSER
+ /**
+ * "External integer variable set to zero by default. If yydebug
+ * is given a nonzero value, the parser will output information on
+ * input symbols and parser action. See section Debugging Your Parser."
+ */
+# define YYDEBUG 1
+
+ extern int XPathdebug;
+ XPathdebug = 1;
+#endif
+
+ Q_ASSERT(parseInfo);
+
+ const Tokenizer::Token tok(parseInfo->tokenizer->nextToken(sourceLocator));
+
+ (*lexVal).sval = tok.value;
+
+ return static_cast<int>(tok.type);
+}
+
+/**
+ * @short Creates a path expression which contains the step <tt>//</tt> between
+ * @p begin and and @p end.
+ *
+ * <tt>begin//end</tt> is a short form for: <tt>begin/descendant-or-self::node()/end</tt>
+ *
+ * This will be compiled as two-path expression: <tt>(/)/(//.)/step/</tt>
+ */
+static Expression::Ptr createSlashSlashPath(const Expression::Ptr &begin,
+ const Expression::Ptr &end,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr twoSlash(create(new AxisStep(QXmlNodeModelIndex::AxisDescendantOrSelf, BuiltinTypes::node), sourceLocator, parseInfo));
+ const Expression::Ptr p1(create(new Path(begin, twoSlash), sourceLocator, parseInfo));
+
+ return create(new Path(p1, end), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates a call to <tt>fn:concat()</tt> with @p args as the arguments.
+ */
+static inline Expression::Ptr createConcatFN(const ParserContext *const parseInfo,
+ const Expression::List &args,
+ const YYLTYPE &sourceLocator)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::concat);
+ const ReflectYYLTYPE ryy(sourceLocator, parseInfo);
+
+ return create(parseInfo->staticContext->functionSignatures()->createFunctionCall(name, args, parseInfo->staticContext, &ryy),
+ sourceLocator, parseInfo);
+}
+
+static inline Expression::Ptr createDirAttributeValue(const Expression::List &content,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator)
+{
+ if(content.isEmpty())
+ return create(new EmptySequence(), sourceLocator, parseInfo);
+ else if(content.size() == 1)
+ return content.first();
+ else
+ return createConcatFN(parseInfo, content, sourceLocator);
+}
+
+/**
+ * @short Checks for variable initialization circularity.
+ *
+ * "A recursive function that checks for recursion is full of ironies."
+ *
+ * -- The Salsa Master
+ *
+ * Issues an error via @p parseInfo's StaticContext if the initialization
+ * expression @p checkee for the global variable @p var, contains a variable
+ * reference to @p var. That is, if there's a circularity.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#ERRXQST0054">XQuery 1.0: An XML
+ * Query Language, err:XQST0054</a>
+ */
+static void checkVariableCircularity(const VariableDeclaration::Ptr &var,
+ const Expression::Ptr &checkee,
+ const VariableDeclaration::Type type,
+ FunctionSignature::List &signList,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(var);
+ Q_ASSERT(checkee);
+ Q_ASSERT(parseInfo);
+
+ const Expression::ID id = checkee->id();
+
+ if(id == Expression::IDExpressionVariableReference)
+ {
+ const ExpressionVariableReference *const ref =
+ static_cast<const ExpressionVariableReference *>(checkee.data());
+
+ if(var->slot == ref->slot() && type == ref->variableDeclaration()->type)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The initialization of variable %1 "
+ "depends on itself").arg(formatKeyword(var, parseInfo->staticContext->namePool())),
+ parseInfo->isXSLT() ? ReportContext::XTDE0640 : ReportContext::XQST0054, ref);
+ return;
+ }
+ else
+ {
+ /* If the variable we're checking is below another variable, it can be a recursive
+ * dependency through functions, so we need to check variable references too. */
+ checkVariableCircularity(var, ref->sourceExpression(), type, signList, parseInfo);
+ return;
+ }
+ }
+ else if(id == Expression::IDUserFunctionCallsite)
+ {
+ const UserFunctionCallsite::Ptr callsite(checkee);
+ const FunctionSignature::Ptr sign(callsite->callTargetDescription());
+ const FunctionSignature::List::const_iterator end(signList.constEnd());
+ FunctionSignature::List::const_iterator it(signList.constBegin());
+ bool noMatch = true;
+
+ for(; it != end; ++it)
+ {
+ if(*it == sign)
+ {
+ /* The variable we're checking is depending on a function that's recursive. The
+ * user has written a weird query, in other words. Since it's the second time
+ * we've encountered a callsite, we now skip it. */
+ noMatch = false;
+ break;
+ }
+ }
+
+ if(noMatch)
+ {
+ signList.append(sign);
+ /* Check the body of the function being called. */
+ checkVariableCircularity(var, callsite->body(), type, signList, parseInfo);
+ }
+ /* Continue with the operands, such that we also check the arguments of the callsite. */
+ }
+ else if(id == Expression::IDUnresolvedVariableReference)
+ {
+ /* We're called before it has rewritten itself. */
+ checkVariableCircularity(var, checkee->as<UnresolvedVariableReference>()->replacement(), type, signList, parseInfo);
+ }
+
+ /* Check the operands. */
+ const Expression::List ops(checkee->operands());
+ if(ops.isEmpty())
+ return;
+
+ const Expression::List::const_iterator end(ops.constEnd());
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ checkVariableCircularity(var, *it, type, signList, parseInfo);
+}
+
+static void variableUnavailable(const QXmlName &variableName,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &location)
+{
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No variable with name %1 exists")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), variableName)),
+ ReportContext::XPST0008, fromYYLTYPE(location, parseInfo));
+}
+
+/**
+ * The Cardinality in a TypeDeclaration for a variable in a quantification has no effect,
+ * and this function ensures this by changing @p type to Cardinality Cardinality::zeroOrMore().
+ *
+ * @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=3305">Bugzilla Bug 3305
+ * Cardinality + on range variables</a>
+ * @see ParserContext::finalizePushedVariable()
+ */
+static inline SequenceType::Ptr quantificationType(const SequenceType::Ptr &type)
+{
+ Q_ASSERT(type);
+ return makeGenericSequenceType(type->itemType(), Cardinality::zeroOrMore());
+}
+
+/**
+ * @p seqType and @p expr may be @c null.
+ */
+static Expression::Ptr pushVariable(const QXmlName name,
+ const SequenceType::Ptr &seqType,
+ const Expression::Ptr &expr,
+ const VariableDeclaration::Type type,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool checkSource = true)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* -2 will cause Q_ASSERTs to trigger if it isn't changed. */
+ VariableSlotID slot = -2;
+
+ switch(type)
+ {
+ case VariableDeclaration::FunctionArgument:
+ /* Fallthrough. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ slot = parseInfo->allocateExpressionSlot();
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ {
+ slot = parseInfo->allocateGlobalVariableSlot();
+ break;
+ }
+ case VariableDeclaration::RangeVariable:
+ {
+ slot = parseInfo->staticContext->allocateRangeSlot();
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ slot = parseInfo->allocatePositionalSlot();
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ /* Fallthrough. We do nothing, template parameters
+ * doesn't use context slots at all, they're hashed
+ * on the name. */
+ case VariableDeclaration::ExternalVariable:
+ /* We do nothing, external variables doesn't use
+ *context slots/stack frames at all. */
+ ;
+ }
+
+ const VariableDeclaration::Ptr var(new VariableDeclaration(name, slot, type, seqType));
+
+ Expression::Ptr checked;
+
+ if(checkSource && seqType)
+ {
+ if(expr)
+ {
+ /* We only want to add conversion for function arguments, and variables
+ * if we're XSL-T.
+ *
+ * We unconditionally skip TypeChecker::CheckFocus because the StaticContext we
+ * pass hasn't set up the focus yet, since that's the parent's responsibility. */
+ const TypeChecker::Options options(( type == VariableDeclaration::FunctionArgument
+ || type == VariableDeclaration::TemplateParameter
+ || parseInfo->isXSLT())
+ ? TypeChecker::AutomaticallyConvert : TypeChecker::Options());
+
+ checked = TypeChecker::applyFunctionConversion(expr, seqType, parseInfo->staticContext,
+ parseInfo->isXSLT() ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ options);
+ }
+ }
+ else
+ checked = expr;
+
+ /* Add an evaluation cache for all expression variables. No EvaluationCache is needed for
+ * positional variables because in the end they are calls to Iterator::position(). Similarly,
+ * no need to cache range variables either because they are calls to DynamicContext::rangeVariable().
+ *
+ * We don't do it for function arguments because the Expression being cached depends -- it depends
+ * on the callsite. UserFunctionCallsite is responsible for the evaluation caches in that case.
+ *
+ * In some cases the EvaluationCache instance isn't necessary, but in those cases EvaluationCache
+ * optimizes itself away. */
+ if(type == VariableDeclaration::ExpressionVariable)
+ checked = create(new EvaluationCache<false>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+ else if(type == VariableDeclaration::GlobalVariable)
+ checked = create(new EvaluationCache<true>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+
+ var->setExpression(checked);
+
+ parseInfo->variables.push(var);
+ return checked;
+}
+
+static inline VariableDeclaration::Ptr variableByName(const QXmlName name,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* We walk the list backwards. */
+ const VariableDeclaration::Stack::const_iterator start(parseInfo->variables.constBegin());
+ VariableDeclaration::Stack::const_iterator it(parseInfo->variables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ Q_ASSERT(*it);
+ if((*it)->name == name)
+ return *it;
+ }
+
+ return VariableDeclaration::Ptr();
+}
+
+static Expression::Ptr resolveVariable(const QXmlName &name,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool raiseErrorOnUnavailability)
+{
+ const VariableDeclaration::Ptr var(variableByName(name, parseInfo));
+ Expression::Ptr retval;
+
+ if(var && var->type != VariableDeclaration::ExternalVariable)
+ {
+ switch(var->type)
+ {
+ case VariableDeclaration::RangeVariable:
+ {
+ retval = create(new RangeVariableReference(var->expression(), var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ /* Fallthrough. From the perspective of an ExpressionVariableReference, it can't tell
+ * a difference between a global and a local expression variable. However, the cache
+ * mechanism must. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ retval = create(new ExpressionVariableReference(var->slot, var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::FunctionArgument:
+ {
+ retval = create(new ArgumentReference(var->sequenceType, var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ retval = create(new PositionalVariableReference(var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ {
+ retval = create(new TemplateParameterReference(var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::ExternalVariable:
+ /* This code path will never be hit, but the case
+ * label silences a warning. See above. */
+ ;
+ }
+ Q_ASSERT(retval);
+ var->references.append(retval);
+ }
+ else
+ {
+ /* Let's see if your external variable loader can provide us with one. */
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable(name, CommonSequenceTypes::ZeroOrMoreItems));
+
+ if(varType)
+ {
+ const Expression::Ptr extRef(create(new ExternalVariableReference(name, varType), sourceLocator, parseInfo));
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion(extRef, varType, parseInfo->staticContext));
+ retval = checked;
+ }
+ else if(!raiseErrorOnUnavailability && parseInfo->isXSLT())
+ {
+ /* In XSL-T, global variables are in scope for the whole
+ * stylesheet, so we must resolve this first at the end. */
+ retval = create(new UnresolvedVariableReference(name), sourceLocator, parseInfo);
+ parseInfo->unresolvedVariableReferences.insert(name, retval);
+ }
+ else
+ variableUnavailable(name, parseInfo, sourceLocator);
+ }
+
+ return retval;
+}
+
+static Expression::Ptr createReturnOrderBy(const OrderSpecTransfer::List &orderSpecTransfer,
+ const Expression::Ptr &returnExpr,
+ const OrderBy::Stability stability,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ // TODO do resize(orderSpec.size() + 1)
+ Expression::List exprs;
+ OrderBy::OrderSpec::Vector orderSpecs;
+
+ exprs.append(returnExpr);
+
+ const int len = orderSpecTransfer.size();
+
+ for(int i = 0; i < len; ++i)
+ {
+ exprs.append(orderSpecTransfer.at(i).expression);
+ orderSpecs.append(orderSpecTransfer.at(i).orderSpec);
+ }
+
+ return create(new ReturnOrderBy(stability, orderSpecs, exprs), sourceLocator, parseInfo);
+}
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ END_OF_FILE = 0,
+ STRING_LITERAL = 258,
+ NON_BOUNDARY_WS = 259,
+ XPATH2_STRING_LITERAL = 260,
+ QNAME = 261,
+ NCNAME = 262,
+ CLARK_NAME = 263,
+ ANY_LOCAL_NAME = 264,
+ ANY_PREFIX = 265,
+ NUMBER = 266,
+ XPATH2_NUMBER = 267,
+ ANCESTOR = 268,
+ ANCESTOR_OR_SELF = 269,
+ AND = 270,
+ APOS = 271,
+ APPLY_TEMPLATE = 272,
+ AS = 273,
+ ASCENDING = 274,
+ ASSIGN = 275,
+ AT = 276,
+ AT_SIGN = 277,
+ ATTRIBUTE = 278,
+ AVT = 279,
+ BAR = 280,
+ BASEURI = 281,
+ BEGIN_END_TAG = 282,
+ BOUNDARY_SPACE = 283,
+ BY = 284,
+ CALL_TEMPLATE = 285,
+ CASE = 286,
+ CASTABLE = 287,
+ CAST = 288,
+ CHILD = 289,
+ COLLATION = 290,
+ COLONCOLON = 291,
+ COMMA = 292,
+ COMMENT = 293,
+ COMMENT_START = 294,
+ CONSTRUCTION = 295,
+ COPY_NAMESPACES = 296,
+ CURLY_LBRACE = 297,
+ CURLY_RBRACE = 298,
+ DECLARE = 299,
+ DEFAULT = 300,
+ DESCENDANT = 301,
+ DESCENDANT_OR_SELF = 302,
+ DESCENDING = 303,
+ DIV = 304,
+ DOCUMENT = 305,
+ DOCUMENT_NODE = 306,
+ DOLLAR = 307,
+ DOT = 308,
+ DOTDOT = 309,
+ ELEMENT = 310,
+ ELSE = 311,
+ EMPTY = 312,
+ EMPTY_SEQUENCE = 313,
+ ENCODING = 314,
+ END_SORT = 315,
+ EQ = 316,
+ ERROR = 317,
+ EVERY = 318,
+ EXCEPT = 319,
+ EXTERNAL = 320,
+ FOLLOWING = 321,
+ FOLLOWING_SIBLING = 322,
+ FOLLOWS = 323,
+ FOR_APPLY_TEMPLATE = 324,
+ FOR = 325,
+ FUNCTION = 326,
+ GE = 327,
+ G_EQ = 328,
+ G_GE = 329,
+ G_GT = 330,
+ G_LE = 331,
+ G_LT = 332,
+ G_NE = 333,
+ GREATEST = 334,
+ GT = 335,
+ IDIV = 336,
+ IF = 337,
+ IMPORT = 338,
+ INHERIT = 339,
+ IN = 340,
+ INSTANCE = 341,
+ INTERSECT = 342,
+ IS = 343,
+ ITEM = 344,
+ LAX = 345,
+ LBRACKET = 346,
+ LEAST = 347,
+ LE = 348,
+ LET = 349,
+ LPAREN = 350,
+ LT = 351,
+ MAP = 352,
+ MATCHES = 353,
+ MINUS = 354,
+ MODE = 355,
+ MOD = 356,
+ MODULE = 357,
+ NAME = 358,
+ NAMESPACE = 359,
+ NE = 360,
+ NODE = 361,
+ NO_INHERIT = 362,
+ NO_PRESERVE = 363,
+ OF = 364,
+ OPTION = 365,
+ ORDERED = 366,
+ ORDERING = 367,
+ ORDER = 368,
+ OR = 369,
+ PARENT = 370,
+ PI_START = 371,
+ PLUS = 372,
+ POSITION_SET = 373,
+ PRAGMA_END = 374,
+ PRAGMA_START = 375,
+ PRECEDES = 376,
+ PRECEDING = 377,
+ PRECEDING_SIBLING = 378,
+ PRESERVE = 379,
+ PRIORITY = 380,
+ PROCESSING_INSTRUCTION = 381,
+ QUESTION = 382,
+ QUICK_TAG_END = 383,
+ QUOTE = 384,
+ RBRACKET = 385,
+ RETURN = 386,
+ RPAREN = 387,
+ SATISFIES = 388,
+ SCHEMA_ATTRIBUTE = 389,
+ SCHEMA_ELEMENT = 390,
+ SCHEMA = 391,
+ SELF = 392,
+ SEMI_COLON = 393,
+ SLASH = 394,
+ SLASHSLASH = 395,
+ SOME = 396,
+ SORT = 397,
+ STABLE = 398,
+ STAR = 399,
+ STRICT = 400,
+ STRIP = 401,
+ SUCCESS = 402,
+ COMMENT_CONTENT = 403,
+ PI_CONTENT = 404,
+ PI_TARGET = 405,
+ XSLT_VERSION = 406,
+ TEMPLATE = 407,
+ TEXT = 408,
+ THEN = 409,
+ TO = 410,
+ TREAT = 411,
+ TUNNEL = 412,
+ TYPESWITCH = 413,
+ UNION = 414,
+ UNORDERED = 415,
+ VALIDATE = 416,
+ VARIABLE = 417,
+ VERSION = 418,
+ WHERE = 419,
+ XQUERY = 420,
+ INTERNAL = 421,
+ INTERNAL_NAME = 422,
+ CURRENT = 423
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+/* Line 221 of yacc.c. */
+#line 1323 "qquerytransformparser.cpp"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ YYLTYPE yyls;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 5
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 2052
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 169
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 237
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 472
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 812
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 423
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 6, 9, 10, 16, 17, 20, 23,
+ 26, 33, 34, 37, 40, 43, 46, 49, 52, 55,
+ 58, 66, 67, 68, 84, 85, 88, 89, 91, 94,
+ 96, 98, 100, 102, 104, 106, 108, 110, 112, 114,
+ 122, 127, 129, 131, 133, 135, 142, 149, 155, 160,
+ 162, 164, 170, 173, 176, 183, 185, 187, 189, 191,
+ 197, 203, 210, 211, 215, 219, 226, 227, 231, 232,
+ 235, 237, 241, 251, 253, 256, 257, 260, 265, 267,
+ 269, 270, 282, 283, 285, 289, 293, 295, 297, 301,
+ 303, 305, 309, 311, 313, 316, 319, 321, 325, 329,
+ 331, 333, 337, 341, 343, 345, 347, 351, 355, 357,
+ 359, 361, 363, 365, 370, 371, 374, 375, 378, 380,
+ 384, 386, 388, 390, 392, 393, 394, 405, 406, 407,
+ 418, 420, 422, 424, 425, 429, 430, 440, 441, 450,
+ 452, 454, 456, 460, 466, 467, 469, 472, 476, 478,
+ 483, 484, 486, 488, 489, 491, 492, 495, 499, 503,
+ 506, 508, 510, 511, 512, 522, 523, 524, 534, 536,
+ 537, 538, 548, 549, 550, 560, 562, 565, 566, 573,
+ 574, 575, 584, 586, 588, 589, 593, 597, 598, 605,
+ 614, 616, 620, 622, 626, 628, 630, 632, 634, 636,
+ 640, 642, 646, 648, 650, 652, 656, 658, 660, 662,
+ 664, 666, 670, 672, 676, 678, 680, 682, 684, 686,
+ 691, 693, 698, 700, 705, 707, 712, 714, 717, 719,
+ 721, 723, 725, 727, 731, 733, 735, 737, 739, 741,
+ 743, 747, 749, 751, 753, 755, 757, 759, 763, 765,
+ 767, 769, 772, 774, 777, 780, 783, 786, 790, 793,
+ 795, 800, 801, 803, 806, 809, 811, 813, 815, 819,
+ 827, 831, 833, 835, 838, 839, 843, 849, 850, 860,
+ 866, 867, 870, 871, 873, 877, 878, 882, 888, 889,
+ 891, 892, 895, 897, 899, 901, 903, 908, 910, 912,
+ 913, 917, 919, 921, 923, 926, 928, 930, 932, 934,
+ 936, 938, 940, 942, 944, 946, 948, 950, 951, 955,
+ 957, 959, 961, 963, 965, 967, 969, 971, 973, 975,
+ 977, 979, 984, 986, 988, 990, 992, 994, 996, 998,
+ 1004, 1006, 1008, 1010, 1012, 1015, 1017, 1019, 1023, 1026,
+ 1028, 1031, 1036, 1037, 1039, 1041, 1043, 1045, 1047, 1049,
+ 1051, 1052, 1053, 1062, 1064, 1070, 1071, 1074, 1078, 1082,
+ 1086, 1087, 1090, 1093, 1094, 1097, 1100, 1103, 1106, 1109,
+ 1113, 1115, 1117, 1119, 1121, 1123, 1125, 1127, 1131, 1132,
+ 1138, 1139, 1141, 1146, 1150, 1154, 1158, 1159, 1160, 1164,
+ 1166, 1168, 1170, 1172, 1174, 1176, 1180, 1182, 1185, 1186,
+ 1189, 1192, 1195, 1196, 1198, 1200, 1202, 1204, 1206, 1208,
+ 1211, 1213, 1215, 1217, 1219, 1221, 1223, 1225, 1227, 1230,
+ 1233, 1238, 1240, 1242, 1245, 1248, 1251, 1256, 1261, 1263,
+ 1265, 1268, 1273, 1278, 1285, 1292, 1297, 1300, 1305, 1310,
+ 1318, 1326, 1327, 1329, 1334, 1337, 1339, 1341, 1343, 1345,
+ 1347, 1349, 1351, 1353, 1356, 1358, 1360, 1362, 1364, 1366,
+ 1368, 1370, 1372
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 170, 0, -1, 171, 174, -1, 171, 173, -1, -1,
+ 165, 163, 404, 172, 185, -1, -1, 59, 404, -1,
+ 176, 219, -1, 175, 176, -1, 102, 104, 7, 73,
+ 403, 185, -1, -1, 176, 189, -1, 176, 183, -1,
+ 176, 186, -1, 176, 184, -1, 176, 177, -1, 176,
+ 208, -1, 176, 213, -1, 176, 192, -1, 44, 152,
+ 182, 317, 377, 305, 185, -1, -1, -1, 44, 152,
+ 181, 98, 95, 178, 220, 179, 132, 228, 180, 317,
+ 377, 305, 185, -1, -1, 125, 404, -1, -1, 182,
+ -1, 103, 397, -1, 187, -1, 200, -1, 201, -1,
+ 211, -1, 193, -1, 195, -1, 197, -1, 202, -1,
+ 204, -1, 138, -1, 44, 104, 7, 73, 403, 364,
+ 185, -1, 44, 28, 188, 185, -1, 146, -1, 124,
+ -1, 190, -1, 191, -1, 44, 45, 55, 104, 403,
+ 185, -1, 44, 45, 71, 104, 403, 185, -1, 44,
+ 110, 397, 404, 185, -1, 44, 112, 194, 185, -1,
+ 111, -1, 160, -1, 44, 45, 113, 196, 185, -1,
+ 57, 92, -1, 57, 79, -1, 44, 41, 198, 37,
+ 199, 185, -1, 124, -1, 108, -1, 84, -1, 107,
+ -1, 44, 45, 35, 404, 185, -1, 44, 26, 364,
+ 403, 185, -1, 83, 136, 203, 403, 206, 185, -1,
+ -1, 45, 55, 104, -1, 104, 7, 73, -1, 83,
+ 102, 205, 403, 206, 185, -1, -1, 104, 7, 73,
+ -1, -1, 21, 207, -1, 403, -1, 207, 37, 403,
+ -1, 44, 162, 364, 52, 341, 377, 209, 210, 185,
+ -1, 65, -1, 20, 227, -1, -1, 20, 227, -1,
+ 44, 40, 212, 185, -1, 146, -1, 124, -1, -1,
+ 44, 71, 364, 399, 95, 215, 132, 214, 377, 217,
+ 185, -1, -1, 216, -1, 215, 37, 216, -1, 52,
+ 341, 377, -1, 65, -1, 218, -1, 42, 225, 43,
+ -1, 225, -1, 221, -1, 220, 25, 221, -1, 223,
+ -1, 139, -1, 139, 223, -1, 140, 223, -1, 222,
+ -1, 222, 139, 223, -1, 222, 140, 223, -1, 345,
+ -1, 224, -1, 223, 139, 224, -1, 223, 140, 224,
+ -1, 322, -1, 227, -1, 226, -1, 227, 37, 227,
+ -1, 226, 37, 227, -1, 277, -1, 232, -1, 253,
+ -1, 267, -1, 276, -1, 24, 95, 356, 132, -1,
+ -1, 100, 230, -1, -1, 100, 231, -1, 231, -1,
+ 230, 37, 231, -1, 405, -1, 7, -1, 233, -1,
+ 240, -1, -1, -1, 70, 52, 341, 377, 239, 85,
+ 227, 234, 235, 236, -1, -1, -1, 37, 52, 341,
+ 377, 239, 85, 227, 237, 238, 236, -1, 244, -1,
+ 233, -1, 240, -1, -1, 21, 52, 341, -1, -1,
+ 94, 364, 52, 341, 377, 20, 227, 241, 242, -1,
+ -1, 37, 52, 341, 377, 20, 227, 243, 242, -1,
+ 244, -1, 233, -1, 240, -1, 245, 131, 227, -1,
+ 164, 227, 245, 131, 227, -1, -1, 246, -1, 252,
+ 247, -1, 247, 37, 248, -1, 248, -1, 227, 249,
+ 250, 251, -1, -1, 19, -1, 48, -1, -1, 196,
+ -1, -1, 35, 403, -1, 166, 35, 227, -1, 143,
+ 113, 29, -1, 113, 29, -1, 254, -1, 260, -1,
+ -1, -1, 141, 52, 341, 377, 85, 227, 255, 256,
+ 257, -1, -1, -1, 37, 52, 341, 377, 85, 227,
+ 258, 259, 257, -1, 266, -1, -1, -1, 63, 52,
+ 341, 377, 85, 227, 261, 262, 263, -1, -1, -1,
+ 37, 52, 341, 377, 85, 227, 264, 265, 263, -1,
+ 266, -1, 133, 227, -1, -1, 158, 95, 225, 132,
+ 268, 269, -1, -1, -1, 31, 273, 378, 270, 131,
+ 227, 271, 272, -1, 269, -1, 274, -1, -1, 52,
+ 397, 18, -1, 45, 131, 227, -1, -1, 45, 52,
+ 397, 275, 131, 227, -1, 82, 95, 225, 132, 154,
+ 227, 56, 227, -1, 278, -1, 277, 114, 278, -1,
+ 279, -1, 278, 15, 279, -1, 280, -1, 298, -1,
+ 296, -1, 300, -1, 281, -1, 281, 155, 281, -1,
+ 283, -1, 281, 282, 283, -1, 117, -1, 99, -1,
+ 285, -1, 283, 284, 285, -1, 144, -1, 49, -1,
+ 81, -1, 101, -1, 286, -1, 285, 287, 286, -1,
+ 289, -1, 286, 288, 289, -1, 159, -1, 25, -1,
+ 87, -1, 64, -1, 290, -1, 290, 86, 109, 378,
+ -1, 291, -1, 291, 156, 18, 378, -1, 292, -1,
+ 292, 32, 18, 376, -1, 293, -1, 293, 33, 18,
+ 376, -1, 295, -1, 294, 293, -1, 117, -1, 99,
+ -1, 302, -1, 309, -1, 304, -1, 280, 297, 280,
+ -1, 73, -1, 78, -1, 74, -1, 75, -1, 76,
+ -1, 77, -1, 280, 299, 280, -1, 61, -1, 105,
+ -1, 72, -1, 80, -1, 93, -1, 96, -1, 280,
+ 301, 280, -1, 88, -1, 121, -1, 68, -1, 303,
+ 218, -1, 161, -1, 161, 145, -1, 161, 90, -1,
+ 306, 305, -1, 42, 43, -1, 42, 225, 43, -1,
+ 306, 307, -1, 307, -1, 120, 402, 308, 119, -1,
+ -1, 404, -1, 139, 310, -1, 140, 310, -1, 139,
+ -1, 310, -1, 311, -1, 310, 321, 311, -1, 310,
+ 321, 142, 246, 131, 311, 60, -1, 310, 140, 311,
+ -1, 322, -1, 336, -1, 168, 218, -1, -1, 151,
+ 312, 218, -1, 26, 404, 42, 225, 43, -1, -1,
+ 44, 104, 7, 73, 3, 42, 313, 225, 43, -1,
+ 30, 397, 95, 314, 132, -1, -1, 315, 316, -1,
+ -1, 318, -1, 316, 37, 318, -1, -1, 95, 316,
+ 132, -1, 319, 52, 341, 377, 320, -1, -1, 157,
+ -1, -1, 20, 227, -1, 139, -1, 97, -1, 69,
+ -1, 323, -1, 322, 91, 225, 130, -1, 324, -1,
+ 331, -1, -1, 327, 325, 326, -1, 329, -1, 333,
+ -1, 389, -1, 328, 36, -1, 14, -1, 13, -1,
+ 23, -1, 34, -1, 47, -1, 46, -1, 66, -1,
+ 122, -1, 67, -1, 123, -1, 115, -1, 137, -1,
+ -1, 22, 330, 333, -1, 333, -1, 389, -1, 332,
+ -1, 54, -1, 334, -1, 382, -1, 397, -1, 335,
+ -1, 144, -1, 9, -1, 10, -1, 337, -1, 336,
+ 91, 225, 130, -1, 338, -1, 340, -1, 342, -1,
+ 343, -1, 345, -1, 344, -1, 347, -1, 17, 229,
+ 95, 314, 132, -1, 339, -1, 404, -1, 12, -1,
+ 11, -1, 52, 341, -1, 7, -1, 405, -1, 95,
+ 225, 132, -1, 95, 132, -1, 53, -1, 194, 218,
+ -1, 399, 95, 346, 132, -1, -1, 227, -1, 226,
+ -1, 348, -1, 360, -1, 349, -1, 358, -1, 359,
+ -1, -1, -1, 77, 401, 350, 353, 351, 118, 353,
+ 352, -1, 128, -1, 75, 357, 27, 397, 75, -1,
+ -1, 353, 354, -1, 401, 73, 355, -1, 129, 356,
+ 129, -1, 16, 356, 16, -1, -1, 218, 356, -1,
+ 404, 356, -1, -1, 357, 348, -1, 357, 404, -1,
+ 357, 4, -1, 357, 218, -1, 39, 148, -1, 116,
+ 150, 149, -1, 361, -1, 362, -1, 365, -1, 366,
+ -1, 367, -1, 368, -1, 375, -1, 50, 364, 218,
+ -1, -1, 55, 364, 372, 363, 305, -1, -1, 166,
+ -1, 23, 364, 369, 305, -1, 153, 364, 218, -1,
+ 38, 364, 218, -1, 126, 374, 305, -1, -1, -1,
+ 370, 397, 371, -1, 373, -1, 397, -1, 373, -1,
+ 218, -1, 7, -1, 218, -1, 104, 218, 218, -1,
+ 381, -1, 381, 127, -1, -1, 18, 378, -1, 380,
+ 379, -1, 58, 395, -1, -1, 117, -1, 144, -1,
+ 127, -1, 381, -1, 382, -1, 389, -1, 89, 395,
+ -1, 397, -1, 384, -1, 392, -1, 394, -1, 388,
+ -1, 387, -1, 386, -1, 383, -1, 106, 395, -1,
+ 51, 395, -1, 51, 95, 385, 132, -1, 392, -1,
+ 394, -1, 153, 395, -1, 38, 395, -1, 126, 395,
+ -1, 126, 95, 7, 132, -1, 126, 95, 404, 132,
+ -1, 390, -1, 391, -1, 23, 395, -1, 23, 95,
+ 144, 132, -1, 23, 95, 396, 132, -1, 23, 95,
+ 396, 37, 398, 132, -1, 23, 95, 144, 37, 398,
+ 132, -1, 134, 95, 397, 132, -1, 55, 395, -1,
+ 55, 95, 144, 132, -1, 55, 95, 397, 132, -1,
+ 55, 95, 397, 37, 398, 393, 132, -1, 55, 95,
+ 144, 37, 398, 393, 132, -1, -1, 127, -1, 135,
+ 95, 397, 132, -1, 95, 132, -1, 7, -1, 405,
+ -1, 7, -1, 405, -1, 397, -1, 400, -1, 405,
+ -1, 7, -1, 167, 7, -1, 7, -1, 6, -1,
+ 7, -1, 405, -1, 404, -1, 3, -1, 5, -1,
+ 6, -1, 8, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 1375, 1375, 1376, 1378, 1379, 1410, 1411, 1427, 1525,
+ 1527, 1533, 1535, 1542, 1548, 1554, 1561, 1564, 1568, 1572,
+ 1592, 1606, 1610, 1604, 1673, 1677, 1694, 1697, 1699, 1704,
+ 1705, 1709, 1710, 1714, 1718, 1722, 1724, 1725, 1727, 1729,
+ 1775, 1789, 1794, 1799, 1800, 1802, 1817, 1832, 1842, 1857,
+ 1861, 1866, 1880, 1884, 1889, 1903, 1908, 1913, 1918, 1923,
+ 1939, 1962, 1970, 1971, 1972, 1974, 1991, 1992, 1994, 1995,
+ 1997, 1998, 2000, 2055, 2059, 2065, 2068, 2073, 2087, 2091,
+ 2097, 2096, 2205, 2208, 2214, 2235, 2241, 2245, 2247, 2252,
+ 2262, 2263, 2268, 2269, 2278, 2348, 2359, 2360, 2364, 2369,
+ 2438, 2439, 2443, 2448, 2492, 2493, 2498, 2505, 2511, 2512,
+ 2513, 2514, 2515, 2516, 2522, 2527, 2533, 2536, 2541, 2547,
+ 2553, 2557, 2582, 2583, 2587, 2591, 2585, 2632, 2635, 2630,
+ 2651, 2652, 2653, 2656, 2660, 2668, 2667, 2681, 2680, 2689,
+ 2690, 2691, 2693, 2701, 2712, 2715, 2717, 2722, 2729, 2736,
+ 2742, 2762, 2767, 2773, 2776, 2778, 2779, 2786, 2792, 2796,
+ 2801, 2802, 2805, 2809, 2804, 2819, 2823, 2818, 2831, 2834,
+ 2838, 2833, 2848, 2852, 2847, 2860, 2862, 2890, 2889, 2901,
+ 2909, 2900, 2920, 2921, 2924, 2928, 2933, 2938, 2937, 2953,
+ 2959, 2960, 2966, 2967, 2973, 2974, 2975, 2976, 2978, 2979,
+ 2985, 2986, 2992, 2993, 2995, 2996, 3002, 3003, 3004, 3005,
+ 3007, 3008, 3018, 3019, 3025, 3026, 3028, 3032, 3037, 3038,
+ 3045, 3046, 3052, 3053, 3059, 3060, 3066, 3067, 3073, 3077,
+ 3082, 3083, 3084, 3086, 3092, 3093, 3094, 3095, 3096, 3097,
+ 3099, 3104, 3105, 3106, 3107, 3108, 3109, 3111, 3116, 3117,
+ 3118, 3120, 3134, 3135, 3136, 3138, 3155, 3159, 3164, 3165,
+ 3167, 3172, 3173, 3175, 3181, 3185, 3191, 3194, 3195, 3199,
+ 3208, 3213, 3217, 3218, 3223, 3222, 3237, 3245, 3244, 3260,
+ 3268, 3268, 3277, 3279, 3282, 3287, 3289, 3293, 3359, 3362,
+ 3368, 3371, 3380, 3384, 3388, 3393, 3394, 3399, 3400, 3403,
+ 3402, 3432, 3434, 3435, 3437, 3481, 3482, 3483, 3484, 3485,
+ 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3495, 3494, 3505,
+ 3516, 3521, 3523, 3528, 3529, 3534, 3538, 3540, 3544, 3553,
+ 3560, 3561, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574,
+ 3584, 3585, 3590, 3595, 3601, 3607, 3612, 3617, 3622, 3628,
+ 3633, 3638, 3668, 3672, 3679, 3681, 3685, 3690, 3691, 3692,
+ 3726, 3735, 3724, 3976, 3980, 4000, 4003, 4009, 4014, 4019,
+ 4025, 4028, 4038, 4045, 4049, 4055, 4069, 4075, 4092, 4097,
+ 4110, 4111, 4112, 4113, 4114, 4115, 4116, 4118, 4126, 4125,
+ 4165, 4168, 4173, 4188, 4193, 4200, 4212, 4216, 4212, 4222,
+ 4224, 4228, 4230, 4245, 4249, 4258, 4263, 4267, 4273, 4276,
+ 4281, 4286, 4291, 4292, 4293, 4294, 4296, 4297, 4298, 4299,
+ 4304, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4348, 4353,
+ 4358, 4364, 4365, 4367, 4372, 4377, 4382, 4387, 4403, 4404,
+ 4406, 4411, 4416, 4420, 4432, 4445, 4455, 4460, 4465, 4470,
+ 4484, 4498, 4499, 4501, 4511, 4513, 4518, 4525, 4532, 4534,
+ 4536, 4537, 4539, 4543, 4548, 4549, 4551, 4557, 4559, 4561,
+ 4565, 4570, 4582
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "\"end of file\"", "error", "$undefined", "\"<string literal>\"",
+ "\"<non-boundary text node>\"", "\"<string literal(XPath 2.0)>\"",
+ "\"QName\"", "\"NCName\"", "\"ClarkName\"", "ANY_LOCAL_NAME",
+ "ANY_PREFIX", "\"<number literal>\"", "\"<number literal(XPath 2.0)>\"",
+ "\"ancestor\"", "\"ancestor-or-self\"", "\"and\"", "\"'\"",
+ "\"apply-template\"", "\"as\"", "\"ascending\"", "\":=\"", "\"at\"",
+ "\"@\"", "\"attribute\"", "AVT", "\"|\"", "\"base-uri\"", "\"</\"",
+ "\"boundary-space\"", "\"by\"", "\"call-template\"", "\"case\"",
+ "\"castable\"", "\"cast\"", "\"child\"", "\"collation\"", "\"::\"",
+ "\",\"", "\"comment\"", "\"<!--\"", "\"construction\"",
+ "\"copy-namespaces\"", "\"{\"", "\"}\"", "\"declare\"", "\"default\"",
+ "\"descendant\"", "\"descendant-or-self\"", "\"descending\"", "\"div\"",
+ "\"document\"", "\"document-node\"", "\"$\"", "\".\"", "\"..\"",
+ "\"element\"", "\"else\"", "\"empty\"", "\"empty-sequence\"",
+ "\"encoding\"", "\"end_sort\"", "\"eq\"", "\"unknown keyword\"",
+ "\"every\"", "\"except\"", "\"external\"", "\"following\"",
+ "\"following-sibling\"", "\">>\"", "\"for-apply-template\"", "\"for\"",
+ "\"function\"", "\"ge\"", "\"=\"", "\">=\"", "\">\"", "\"<=\"", "\"<\"",
+ "\"!=\"", "\"greatest\"", "\"gt\"", "\"idiv\"", "\"if\"", "\"import\"",
+ "\"inherit\"", "\"in\"", "\"instance\"", "\"intersect\"", "\"is\"",
+ "\"item\"", "\"lax\"", "\"[\"", "\"least\"", "\"le\"", "\"let\"",
+ "\"(\"", "\"lt\"", "\"map\"", "\"matches\"", "\"-\"", "\"mode\"",
+ "\"mod\"", "\"module\"", "\"name\"", "\"namespace\"", "\"ne\"",
+ "\"node\"", "\"no-inherit\"", "\"no-preserve\"", "\"of\"", "\"option\"",
+ "\"ordered\"", "\"ordering\"", "\"order\"", "\"or\"", "\"parent\"",
+ "\"<?\"", "\"+\"", "POSITION_SET", "\"#)\"", "\"(#\"", "\"<<\"",
+ "\"preceding\"", "\"preceding-sibling\"", "\"preserve\"", "\"priority\"",
+ "\"processing-instruction\"", "\"?\"", "\"/>\"", "\"\\\"\"", "\"]\"",
+ "\"return\"", "\")\"", "\"satisfies\"", "\"schema-attribute\"",
+ "\"schema-element\"", "\"schema\"", "\"self\"", "\";\"", "\"/\"",
+ "\"//\"", "\"some\"", "\"sort\"", "\"stable\"", "\"*\"", "\"strict\"",
+ "\"strip\"", "SUCCESS", "COMMENT_CONTENT", "PI_CONTENT", "PI_TARGET",
+ "XSLT_VERSION", "\"template\"", "\"text\"", "\"then\"", "\"to\"",
+ "\"treat\"", "\"tunnel\"", "\"typeswitch\"", "\"union\"",
+ "\"unordered\"", "\"validate\"", "\"variable\"", "\"version\"",
+ "\"where\"", "\"xquery\"", "\"internal\"", "\"internal-name\"",
+ "\"current\"", "$accept", "Module", "VersionDecl", "Encoding",
+ "MainModule", "LibraryModule", "ModuleDecl", "Prolog", "TemplateDecl",
+ "@1", "@2", "OptionalPriority", "OptionalTemplateName", "TemplateName",
+ "Setter", "Import", "Separator", "NamespaceDecl", "BoundarySpaceDecl",
+ "BoundarySpacePolicy", "DefaultNamespaceDecl",
+ "DeclareDefaultElementNamespace", "DeclareDefaultFunctionNamespace",
+ "OptionDecl", "OrderingModeDecl", "OrderingMode", "EmptyOrderDecl",
+ "OrderingEmptySequence", "CopyNamespacesDecl", "PreserveMode",
+ "InheritMode", "DefaultCollationDecl", "BaseURIDecl", "SchemaImport",
+ "SchemaPrefix", "ModuleImport", "ModuleNamespaceDecl", "FileLocations",
+ "FileLocation", "VarDecl", "VariableValue", "OptionalDefaultValue",
+ "ConstructionDecl", "ConstructionMode", "FunctionDecl", "@3",
+ "ParamList", "Param", "FunctionBody", "EnclosedExpr", "QueryBody",
+ "Pattern", "PathPattern", "IdKeyPattern", "RelativePathPattern",
+ "PatternStep", "Expr", "ExpressionSequence", "ExprSingle",
+ "OptionalModes", "OptionalMode", "Modes", "Mode", "FLWORExpr",
+ "ForClause", "@4", "@5", "ForTail", "@6", "@7", "PositionalVar",
+ "LetClause", "@8", "LetTail", "@9", "WhereClause", "OrderByClause",
+ "MandatoryOrderByClause", "OrderSpecList", "OrderSpec",
+ "DirectionModifier", "EmptynessModifier", "CollationModifier",
+ "OrderByInputOrder", "QuantifiedExpr", "SomeQuantificationExpr", "@10",
+ "@11", "SomeQuantificationTail", "@12", "@13", "EveryQuantificationExpr",
+ "@14", "@15", "EveryQuantificationTail", "@16", "@17", "SatisfiesClause",
+ "TypeswitchExpr", "@18", "CaseClause", "@19", "@20", "CaseTail",
+ "CaseVariable", "CaseDefault", "@21", "IfExpr", "OrExpr", "AndExpr",
+ "ComparisonExpr", "RangeExpr", "AdditiveExpr", "AdditiveOperator",
+ "MultiplicativeExpr", "MultiplyOperator", "UnionExpr",
+ "IntersectExceptExpr", "UnionOperator", "IntersectOperator",
+ "InstanceOfExpr", "TreatExpr", "CastableExpr", "CastExpr", "UnaryExpr",
+ "UnaryOperator", "ValueExpr", "GeneralComp", "GeneralComparisonOperator",
+ "ValueComp", "ValueComparisonOperator", "NodeComp", "NodeOperator",
+ "ValidateExpr", "ValidationMode", "ExtensionExpr",
+ "EnclosedOptionalExpr", "Pragmas", "Pragma", "PragmaContents",
+ "PathExpr", "RelativePathExpr", "StepExpr", "@22", "@23",
+ "TemplateWithParameters", "@24", "TemplateParameters",
+ "OptionalTemplateParameters", "TemplateParameter", "IsTunnel",
+ "OptionalAssign", "MapOrSlash", "FilteredAxisStep", "AxisStep",
+ "ForwardStep", "@25", "NodeTestInAxisStep", "Axis", "AxisToken",
+ "AbbrevForwardStep", "@26", "ReverseStep", "AbbrevReverseStep",
+ "NodeTest", "NameTest", "WildCard", "FilterExpr", "PrimaryExpr",
+ "Literal", "NumericLiteral", "VarRef", "VarName", "ParenthesizedExpr",
+ "ContextItemExpr", "OrderingExpr", "FunctionCallExpr",
+ "FunctionArguments", "Constructor", "DirectConstructor",
+ "DirElemConstructor", "@27", "@28", "DirElemConstructorTail",
+ "DirAttributeList", "Attribute", "DirAttributeValue", "AttrValueContent",
+ "DirElemContent", "DirCommentConstructor", "DirPIConstructor",
+ "ComputedConstructor", "CompDocConstructor", "CompElemConstructor",
+ "@29", "IsInternal", "CompAttrConstructor", "CompTextConstructor",
+ "CompCommentConstructor", "CompPIConstructor", "CompAttributeName",
+ "@30", "@31", "CompElementName", "CompNameExpr", "CompPIName",
+ "CompNamespaceConstructor", "SingleType", "TypeDeclaration",
+ "SequenceType", "OccurrenceIndicator", "ItemType", "AtomicType",
+ "KindTest", "AnyKindTest", "DocumentTest", "AnyElementTest", "TextTest",
+ "CommentTest", "PITest", "AnyAttributeTest", "AttributeTest",
+ "SchemaAttributeTest", "ElementTest", "OptionalQuestionMark",
+ "SchemaElementTest", "EmptyParanteses", "AttributeName", "ElementName",
+ "TypeName", "FunctionName", "NCName", "LexicalName", "PragmaName",
+ "URILiteral", "StringLiteral", "QName", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+ 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,
+ 415, 416, 417, 418, 419, 420, 421, 422, 423
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint16 yyr1[] =
+{
+ 0, 169, 170, 170, 171, 171, 172, 172, 173, 174,
+ 175, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 177, 178, 179, 177, 180, 180, 181, 181, 182, 183,
+ 183, 183, 183, 183, 183, 183, 184, 184, 185, 186,
+ 187, 188, 188, 189, 189, 190, 191, 192, 193, 194,
+ 194, 195, 196, 196, 197, 198, 198, 199, 199, 200,
+ 201, 202, 203, 203, 203, 204, 205, 205, 206, 206,
+ 207, 207, 208, 209, 209, 210, 210, 211, 212, 212,
+ 214, 213, 215, 215, 215, 216, 217, 217, 218, 219,
+ 220, 220, 221, 221, 221, 221, 221, 221, 221, 222,
+ 223, 223, 223, 224, 225, 225, 226, 226, 227, 227,
+ 227, 227, 227, 227, 228, 228, 229, 229, 230, 230,
+ 231, 231, 232, 232, 234, 235, 233, 237, 238, 236,
+ 236, 236, 236, 239, 239, 241, 240, 243, 242, 242,
+ 242, 242, 244, 244, 245, 245, 246, 247, 247, 248,
+ 249, 249, 249, 250, 250, 251, 251, 251, 252, 252,
+ 253, 253, 255, 256, 254, 258, 259, 257, 257, 261,
+ 262, 260, 264, 265, 263, 263, 266, 268, 267, 270,
+ 271, 269, 272, 272, 273, 273, 274, 275, 274, 276,
+ 277, 277, 278, 278, 279, 279, 279, 279, 280, 280,
+ 281, 281, 282, 282, 283, 283, 284, 284, 284, 284,
+ 285, 285, 286, 286, 287, 287, 288, 288, 289, 289,
+ 290, 290, 291, 291, 292, 292, 293, 293, 294, 294,
+ 295, 295, 295, 296, 297, 297, 297, 297, 297, 297,
+ 298, 299, 299, 299, 299, 299, 299, 300, 301, 301,
+ 301, 302, 303, 303, 303, 304, 305, 305, 306, 306,
+ 307, 308, 308, 309, 309, 309, 309, 310, 310, 310,
+ 310, 311, 311, 311, 312, 311, 311, 313, 311, 311,
+ 315, 314, 316, 316, 316, 317, 317, 318, 319, 319,
+ 320, 320, 321, 321, 321, 322, 322, 323, 323, 325,
+ 324, 324, 326, 326, 327, 328, 328, 328, 328, 328,
+ 328, 328, 328, 328, 328, 328, 328, 330, 329, 329,
+ 329, 331, 332, 333, 333, 334, 334, 335, 335, 335,
+ 336, 336, 337, 337, 337, 337, 337, 337, 337, 337,
+ 338, 338, 339, 339, 340, 341, 341, 342, 342, 343,
+ 344, 345, 346, 346, 346, 347, 347, 348, 348, 348,
+ 350, 351, 349, 352, 352, 353, 353, 354, 355, 355,
+ 356, 356, 356, 357, 357, 357, 357, 357, 358, 359,
+ 360, 360, 360, 360, 360, 360, 360, 361, 363, 362,
+ 364, 364, 365, 366, 367, 368, 370, 371, 369, 369,
+ 372, 372, 373, 374, 374, 375, 376, 376, 377, 377,
+ 378, 378, 379, 379, 379, 379, 380, 380, 380, 380,
+ 381, 382, 382, 382, 382, 382, 382, 382, 383, 384,
+ 384, 385, 385, 386, 387, 388, 388, 388, 389, 389,
+ 390, 390, 390, 390, 390, 391, 392, 392, 392, 392,
+ 392, 393, 393, 394, 395, 396, 396, 397, 397, 398,
+ 399, 399, 400, 400, 401, 401, 402, 402, 403, 404,
+ 404, 405, 405
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 2, 2, 0, 5, 0, 2, 2, 2,
+ 6, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+ 7, 0, 0, 15, 0, 2, 0, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 7,
+ 4, 1, 1, 1, 1, 6, 6, 5, 4, 1,
+ 1, 5, 2, 2, 6, 1, 1, 1, 1, 5,
+ 5, 6, 0, 3, 3, 6, 0, 3, 0, 2,
+ 1, 3, 9, 1, 2, 0, 2, 4, 1, 1,
+ 0, 11, 0, 1, 3, 3, 1, 1, 3, 1,
+ 1, 3, 1, 1, 2, 2, 1, 3, 3, 1,
+ 1, 3, 3, 1, 1, 1, 3, 3, 1, 1,
+ 1, 1, 1, 4, 0, 2, 0, 2, 1, 3,
+ 1, 1, 1, 1, 0, 0, 10, 0, 0, 10,
+ 1, 1, 1, 0, 3, 0, 9, 0, 8, 1,
+ 1, 1, 3, 5, 0, 1, 2, 3, 1, 4,
+ 0, 1, 1, 0, 1, 0, 2, 3, 3, 2,
+ 1, 1, 0, 0, 9, 0, 0, 9, 1, 0,
+ 0, 9, 0, 0, 9, 1, 2, 0, 6, 0,
+ 0, 8, 1, 1, 0, 3, 3, 0, 6, 8,
+ 1, 3, 1, 3, 1, 1, 1, 1, 1, 3,
+ 1, 3, 1, 1, 1, 3, 1, 1, 1, 1,
+ 1, 3, 1, 3, 1, 1, 1, 1, 1, 4,
+ 1, 4, 1, 4, 1, 4, 1, 2, 1, 1,
+ 1, 1, 1, 3, 1, 1, 1, 1, 1, 1,
+ 3, 1, 1, 1, 1, 1, 1, 3, 1, 1,
+ 1, 2, 1, 2, 2, 2, 2, 3, 2, 1,
+ 4, 0, 1, 2, 2, 1, 1, 1, 3, 7,
+ 3, 1, 1, 2, 0, 3, 5, 0, 9, 5,
+ 0, 2, 0, 1, 3, 0, 3, 5, 0, 1,
+ 0, 2, 1, 1, 1, 1, 4, 1, 1, 0,
+ 3, 1, 1, 1, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 1, 1, 1, 1, 1, 1, 1, 5,
+ 1, 1, 1, 1, 2, 1, 1, 3, 2, 1,
+ 2, 4, 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 8, 1, 5, 0, 2, 3, 3, 3,
+ 0, 2, 2, 0, 2, 2, 2, 2, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 3, 0, 5,
+ 0, 1, 4, 3, 3, 3, 0, 0, 3, 1,
+ 1, 1, 1, 1, 1, 3, 1, 2, 0, 2,
+ 2, 2, 0, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 4, 1, 1, 2, 2, 2, 4, 4, 1, 1,
+ 2, 4, 4, 6, 6, 4, 2, 4, 4, 7,
+ 7, 0, 1, 4, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 4, 0, 0, 11, 0, 1, 0, 3, 2, 11,
+ 0, 469, 470, 6, 0, 9, 471, 457, 472, 328,
+ 329, 343, 342, 306, 305, 116, 317, 390, 0, 0,
+ 0, 308, 390, 0, 0, 310, 309, 390, 0, 0,
+ 349, 322, 390, 0, 311, 313, 0, 0, 0, 0,
+ 390, 0, 229, 0, 0, 49, 315, 0, 228, 0,
+ 312, 314, 0, 0, 0, 316, 265, 0, 0, 327,
+ 274, 390, 0, 50, 252, 0, 0, 16, 13, 15,
+ 14, 29, 12, 43, 44, 19, 33, 0, 34, 35,
+ 30, 31, 36, 37, 17, 32, 18, 8, 89, 105,
+ 104, 109, 122, 123, 110, 160, 161, 111, 112, 108,
+ 190, 192, 194, 198, 200, 204, 210, 212, 218, 220,
+ 222, 224, 0, 226, 196, 195, 197, 230, 0, 232,
+ 0, 259, 231, 266, 267, 271, 295, 297, 299, 0,
+ 301, 298, 321, 319, 323, 326, 272, 330, 332, 340,
+ 333, 334, 335, 337, 336, 338, 355, 357, 358, 359,
+ 356, 380, 381, 382, 383, 384, 385, 386, 324, 427,
+ 421, 426, 425, 424, 320, 438, 439, 422, 423, 325,
+ 0, 460, 341, 458, 0, 0, 0, 0, 0, 0,
+ 0, 0, 391, 396, 440, 370, 0, 457, 0, 458,
+ 0, 0, 434, 378, 390, 0, 0, 0, 0, 390,
+ 0, 0, 0, 26, 390, 0, 0, 429, 345, 344,
+ 346, 0, 0, 446, 0, 0, 465, 464, 360, 0,
+ 66, 62, 0, 0, 348, 0, 0, 0, 428, 0,
+ 466, 261, 467, 403, 0, 404, 0, 435, 0, 0,
+ 263, 264, 0, 0, 0, 433, 0, 254, 253, 463,
+ 273, 350, 0, 0, 0, 0, 241, 250, 243, 234,
+ 236, 237, 238, 239, 235, 244, 248, 245, 246, 242,
+ 249, 0, 0, 0, 203, 202, 0, 0, 207, 208,
+ 209, 206, 0, 215, 214, 0, 217, 216, 0, 0,
+ 0, 0, 0, 227, 251, 0, 255, 258, 294, 293,
+ 292, 0, 0, 0, 0, 304, 0, 352, 7, 38,
+ 5, 0, 0, 121, 117, 120, 280, 0, 0, 0,
+ 0, 318, 455, 454, 0, 0, 456, 402, 0, 0,
+ 399, 370, 0, 370, 0, 280, 394, 0, 42, 41,
+ 0, 79, 78, 0, 56, 55, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 285, 0, 387,
+ 0, 431, 432, 0, 0, 388, 401, 400, 408, 408,
+ 365, 0, 0, 0, 0, 0, 0, 0, 0, 347,
+ 0, 405, 379, 0, 262, 0, 0, 395, 0, 0,
+ 408, 275, 393, 0, 107, 106, 191, 193, 233, 240,
+ 247, 199, 201, 205, 211, 213, 0, 0, 0, 0,
+ 256, 0, 270, 0, 268, 0, 0, 300, 302, 303,
+ 0, 354, 353, 0, 0, 468, 0, 0, 282, 0,
+ 441, 0, 442, 392, 397, 371, 113, 372, 0, 0,
+ 0, 40, 77, 0, 0, 0, 0, 0, 0, 462,
+ 0, 461, 0, 0, 48, 28, 0, 282, 408, 0,
+ 430, 0, 447, 0, 448, 0, 0, 0, 133, 361,
+ 0, 0, 68, 0, 0, 68, 408, 0, 88, 260,
+ 436, 437, 445, 453, 0, 177, 0, 0, 219, 412,
+ 416, 417, 418, 420, 221, 223, 406, 225, 257, 0,
+ 0, 0, 0, 296, 331, 351, 10, 0, 339, 289,
+ 281, 283, 0, 459, 0, 0, 398, 276, 279, 60,
+ 57, 58, 0, 59, 0, 0, 53, 52, 51, 82,
+ 469, 390, 47, 21, 0, 0, 408, 451, 451, 389,
+ 409, 0, 0, 0, 0, 366, 0, 0, 67, 0,
+ 0, 63, 64, 0, 0, 0, 0, 0, 411, 419,
+ 413, 415, 414, 410, 407, 159, 0, 0, 150, 146,
+ 148, 288, 0, 444, 443, 54, 45, 46, 0, 0,
+ 83, 277, 0, 0, 286, 0, 0, 452, 0, 0,
+ 169, 0, 0, 365, 0, 0, 69, 70, 65, 61,
+ 0, 0, 162, 184, 178, 158, 0, 151, 152, 153,
+ 0, 284, 408, 408, 0, 80, 0, 39, 307, 93,
+ 0, 22, 90, 96, 92, 100, 103, 99, 20, 0,
+ 73, 75, 450, 449, 170, 134, 124, 0, 370, 370,
+ 367, 0, 0, 135, 163, 0, 0, 269, 154, 155,
+ 147, 290, 85, 84, 408, 0, 94, 95, 0, 0,
+ 0, 0, 0, 0, 74, 0, 0, 0, 125, 373,
+ 363, 362, 0, 0, 189, 71, 144, 0, 0, 179,
+ 0, 0, 149, 0, 287, 0, 278, 91, 114, 97,
+ 98, 101, 102, 76, 72, 0, 0, 171, 175, 144,
+ 0, 369, 368, 0, 0, 140, 141, 136, 139, 0,
+ 145, 0, 164, 168, 185, 0, 156, 0, 291, 86,
+ 0, 87, 0, 24, 0, 176, 0, 131, 126, 132,
+ 130, 376, 0, 377, 374, 375, 0, 144, 0, 0,
+ 0, 157, 81, 115, 118, 0, 285, 408, 0, 0,
+ 408, 0, 142, 408, 180, 0, 25, 408, 0, 408,
+ 364, 0, 0, 0, 0, 119, 0, 0, 133, 0,
+ 143, 0, 0, 182, 181, 183, 0, 172, 0, 137,
+ 165, 0, 0, 23, 173, 0, 144, 166, 187, 186,
+ 0, 127, 138, 0, 0, 174, 128, 167, 0, 144,
+ 188, 129
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 2, 3, 185, 7, 8, 9, 10, 77, 593,
+ 669, 756, 366, 367, 78, 79, 320, 80, 81, 350,
+ 82, 83, 84, 85, 86, 87, 88, 458, 89, 356,
+ 532, 90, 91, 92, 386, 93, 383, 560, 606, 94,
+ 641, 676, 95, 353, 96, 664, 589, 590, 730, 341,
+ 97, 631, 632, 633, 634, 635, 98, 99, 100, 733,
+ 189, 753, 324, 101, 102, 678, 709, 738, 806, 809,
+ 553, 103, 686, 717, 796, 718, 719, 720, 579, 580,
+ 619, 659, 692, 512, 104, 105, 654, 687, 722, 797,
+ 803, 106, 644, 677, 707, 794, 800, 708, 107, 567,
+ 614, 725, 774, 784, 656, 785, 804, 108, 109, 110,
+ 111, 112, 113, 287, 114, 292, 115, 116, 295, 298,
+ 117, 118, 119, 120, 121, 122, 123, 124, 281, 125,
+ 282, 126, 283, 127, 128, 129, 306, 130, 131, 393,
+ 132, 133, 134, 253, 626, 437, 438, 520, 468, 521,
+ 522, 694, 312, 135, 136, 137, 314, 427, 138, 139,
+ 140, 190, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 219, 151, 152, 153, 154, 433, 155, 156,
+ 157, 380, 554, 681, 479, 555, 650, 342, 710, 158,
+ 159, 160, 161, 162, 475, 193, 163, 164, 165, 166,
+ 338, 339, 526, 375, 340, 246, 167, 505, 477, 498,
+ 573, 499, 500, 168, 169, 170, 370, 171, 172, 173,
+ 174, 175, 176, 177, 598, 178, 194, 335, 179, 524,
+ 180, 181, 556, 241, 541, 182, 183
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -668
+static const yytype_int16 yypact[] =
+{
+ -63, -28, 185, 86, 337, -668, 117, -668, -668, -668,
+ 734, -668, -668, 181, 253, 156, -668, 213, -668, -668,
+ -668, -668, -668, -668, -668, 212, -668, -12, 230, 337,
+ 342, -668, -38, 189, 298, -668, -668, 188, 272, 353,
+ -668, -668, 71, 316, -668, -668, 318, 239, 276, 134,
+ 188, 900, -668, 334, 282, -668, -668, 233, -668, 367,
+ -668, -668, 133, 290, 295, -668, 1730, 1730, 345, -668,
+ -668, -38, 305, -668, -36, 396, 334, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, 334, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, 369,
+ 370, -668, -668, -668, -668, -668, -668, -668, -668, 307,
+ 389, -668, 601, 173, 24, -22, 32, -668, 338, 267,
+ 393, 394, 1398, -668, -668, -668, -668, -668, 334, -668,
+ 59, -668, -668, 166, -668, 339, -668, -668, -668, 395,
+ -668, -668, -668, -668, -668, -668, 341, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ 340, -668, -668, 347, 337, 291, 360, 493, 373, 349,
+ 1885, 64, -668, 334, -668, 226, 392, -668, 358, -668,
+ 304, 334, -668, -668, 188, 167, 174, 206, 21, 188,
+ 430, 342, -53, 351, 188, 334, 6, -668, -668, -668,
+ -668, 79, 287, -668, 353, 353, -668, -668, -668, 1232,
+ 336, 18, 403, 344, -668, 324, 1232, 334, -668, 308,
+ -668, 337, -668, -668, 23, -668, 416, -668, 342, 342,
+ 166, 166, 353, 334, 334, -668, 1232, -668, -668, -668,
+ -668, -668, 1232, 1232, 1398, 1398, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ -668, 1398, 1398, 1398, -668, -668, 1398, 1398, -668, -668,
+ -668, -668, 1398, -668, -668, 1398, -668, -668, 1398, 352,
+ 447, 448, 449, -668, -668, 1066, -668, -668, -668, -668,
+ -668, 1730, 1564, 1232, 108, -668, 1232, 1232, -668, -668,
+ -668, 337, 461, -668, -668, -668, -668, 282, 374, 378,
+ 282, -668, -668, -668, 0, 51, -668, -668, 416, 342,
+ -668, 226, 343, 226, 1232, -668, -668, 337, -668, -668,
+ 291, -668, -668, 291, -668, -668, 437, 337, 372, 376,
+ 421, 26, 408, 337, 291, 342, 384, -1, 431, -668,
+ 355, -668, -668, 52, 69, -668, -668, -668, 466, 466,
+ -668, 356, 482, 337, 435, 484, 337, 353, 485, -668,
+ 453, -668, -668, 379, -668, 365, 368, -668, 371, 377,
+ 466, -668, -668, 380, -668, -668, 389, -668, -668, -668,
+ -668, 168, 24, -22, 32, -668, 456, 456, 342, 342,
+ -668, 459, -668, 191, -668, 375, 404, -668, -668, -668,
+ 383, 369, 370, 386, 291, -668, 442, 388, -6, 342,
+ -668, 342, -668, -668, -668, -668, -668, -668, 465, 391,
+ 291, -668, -668, 157, 291, 337, 337, 16, 291, -668,
+ 409, -668, 348, 291, -668, -668, 415, -6, 466, 353,
+ -668, 342, -668, 342, -668, 416, 456, 440, 495, 239,
+ 381, 454, 507, 425, 457, 507, 466, 463, -668, -668,
+ -668, -668, -668, -668, 462, -668, 282, 282, -668, 121,
+ -668, -668, -668, -668, -668, -668, 412, -668, -668, 512,
+ 433, 417, 1232, -668, -668, -668, -668, 337, -668, -668,
+ 513, -668, 497, -668, 422, 423, -668, -668, -668, -668,
+ -668, -668, 291, -668, 291, 291, -668, -668, -668, 504,
+ 515, 188, -668, -668, 83, 416, 466, 432, 432, -668,
+ -668, 1232, 508, 476, 450, -668, 492, 1232, -668, 337,
+ 291, -668, -668, 291, 547, 566, 1232, 539, -668, -668,
+ -668, -668, -668, -668, -668, -668, 543, 1730, 62, 536,
+ -668, 419, 353, -668, -668, -668, -668, -668, 353, 84,
+ -668, -668, 291, 1804, -668, 291, 46, -668, 445, 446,
+ -668, 353, 1232, -668, 33, 524, 550, -668, -668, -668,
+ 1232, 515, -668, 537, -668, -668, 528, -668, -668, 421,
+ 1232, -668, 466, 466, 504, -668, 1232, -668, 404, 1899,
+ 1899, 567, -668, 140, 148, -668, 339, -668, -668, 1232,
+ -668, 573, -668, -668, -668, -668, -668, 92, 226, 226,
+ -668, 1232, 337, -668, -668, 342, 456, -668, -668, -23,
+ -668, 574, -668, -668, 466, 552, 148, 148, 1804, 464,
+ 1899, 1899, 1899, 1899, -668, 1232, 291, 11, -668, -668,
+ -668, -668, 582, 472, -668, -668, 10, 47, 584, -668,
+ 337, 569, -668, 1232, -668, 234, -668, -668, 506, 148,
+ 148, -668, -668, -668, -668, 555, 1232, -668, -668, 63,
+ 250, -668, -668, 556, 1232, -668, -668, -668, -668, 479,
+ -668, 559, -668, -668, -668, 481, -668, 1232, -668, -668,
+ 291, -668, 373, 488, 353, -668, 562, -668, -668, -668,
+ -668, -668, 342, -668, -668, -668, 353, 191, 1232, 353,
+ 1232, -668, -668, 578, -668, 337, 521, 466, 353, 542,
+ 466, 487, -668, 466, -668, 373, -668, 466, 534, 466,
+ -668, 600, 1232, 538, 125, -668, 416, 1232, 495, 1232,
+ -668, 1232, -2, -668, -668, -668, 291, -668, 544, -668,
+ -668, 342, 1232, -668, -668, 1232, 10, -668, -668, -668,
+ 11, -668, -668, 47, 490, -668, -668, -668, 1232, 63,
+ -668, -668
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -668, -668, -668, -668, -668, -668, -668, 613, -668, -668,
+ -668, -668, -668, -668, -668, -668, -285, -668, -668, -668,
+ -668, -668, -668, -668, -668, 418, -668, 5, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, 142, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, 4, -668, -51,
+ -668, -668, -35, -668, -397, -340, -47, 317, -255, -668,
+ -668, -668, -641, -668, -619, -668, -668, -174, -668, -668,
+ -142, -583, -668, -159, -668, -657, -109, 216, -668, 27,
+ -668, -668, -668, -668, -668, -668, -668, -668, -157, -668,
+ -668, -668, -668, -668, -152, -668, -668, -667, -668, -668,
+ -125, -668, -668, -668, -668, -668, -668, -668, -668, 387,
+ 385, 131, 366, -668, 397, -668, 361, 359, -668, -668,
+ 362, -668, -668, -668, 535, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -245, -668, 526, -668,
+ -668, 279, -294, -668, -668, 313, -668, 194, -91, 85,
+ -668, -668, -668, -87, -668, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -175, -668, -668, -668, -668, -668,
+ -668, -668, -183, -668, -668, -668, -538, -668, -668, -42,
+ -668, -668, -668, -668, 67, -668, -668, -327, -668, -668,
+ -668, -668, -668, -668, -668, 3, -668, -668, -668, -668,
+ -668, -668, -668, -668, 458, -668, -668, 252, -341, -412,
+ -668, -668, -55, -394, -668, -668, -668, -668, -668, -668,
+ -304, -668, -668, 467, 124, 469, -11, -668, -24, -170,
+ 321, -668, 639, -668, -308, 15, -30
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -463
+static const yytype_int16 yytable[] =
+{
+ 199, 397, 237, 293, 235, 504, 198, 404, 405, 220,
+ 429, 245, 690, 434, 445, 331, 447, 422, 424, 13,
+ 723, 202, 501, 501, -307, 260, 11, 217, 12, 242,
+ 395, 223, 16, 459, 18, 201, 261, 439, 478, 450,
+ 215, 378, 379, 238, 196, 222, -288, 713, 705, 648,
+ 791, 247, 740, 232, 257, 637, 357, 200, 55, 494,
+ 255, 328, 432, 384, 550, 451, 639, 715, 452, 400,
+ 16, 332, 18, 288, 254, 482, 358, 304, 485, 464,
+ 46, 617, 501, 191, 721, 16, 197, 18, 441, 471,
+ 737, 754, 359, 443, 467, 536, 296, -27, 226, 227,
+ 736, 305, 1, 716, 50, 289, 473, 73, 537, 258,
+ 618, 640, 502, 502, 16, 197, 18, 19, 20, 297,
+ 581, 624, 385, 509, 775, 290, 739, 545, 192, 792,
+ 637, 426, 440, 46, 360, 4, 723, 294, 333, 428,
+ 243, 64, 337, 691, 706, 564, 327, 534, 535, 516,
+ 346, 519, 740, 510, 192, 333, 613, 50, 325, 38,
+ 199, 336, 649, 328, 369, 529, 221, 679, 291, 533,
+ 782, 337, 502, 538, 714, 236, 509, 715, 542, 59,
+ 706, 199, 381, 442, 472, 5, 391, 363, 6, 390,
+ 737, 199, 199, 75, 220, 220, 333, 374, 377, 318,
+ 187, 474, 401, 402, 486, 596, 510, 347, 334, 403,
+ 343, 333, 361, 716, 54, 594, 625, 368, 199, 199,
+ 680, 14, 220, 373, 398, 399, 739, 714, 244, 11,
+ 549, 12, 666, 667, 329, 308, 230, 192, 570, 49,
+ 184, 530, 63, 64, 689, 226, 227, 585, 571, 586,
+ 587, 607, 69, 11, 741, 12, 394, 578, 421, 396,
+ 186, 330, 501, 309, 531, 572, 425, 284, 236, 430,
+ 231, 525, 284, 699, 700, 608, 236, 742, 609, 670,
+ 671, 661, 662, 616, 199, 285, 546, 672, 673, 33,
+ 285, 348, 236, 16, 197, 18, 600, 448, 351, 729,
+ 595, 547, 605, 548, 509, 310, 311, 627, -462, 199,
+ 638, 612, 188, 349, 354, 444, 202, 223, 247, 255,
+ 352, 682, 683, 695, 204, 195, 205, 47, 286, 236,
+ 355, 461, 701, 702, 510, 199, 435, 203, 206, 207,
+ 11, 465, 12, 208, 685, 250, 251, 646, 16, 197,
+ 18, 540, 502, 12, 192, 653, 343, 220, 343, 16,
+ 218, 18, 435, 506, 506, 578, 57, 216, 224, 209,
+ 225, 229, 454, 16, 240, 18, 236, 200, 463, 16,
+ 323, 18, 726, 239, 674, 248, 199, 199, 199, 199,
+ 249, 704, 503, 503, 503, 503, 684, 252, 435, 622,
+ 256, 435, 210, 259, 265, 623, 262, 263, 211, 199,
+ 212, 199, 408, 409, 410, 523, 768, 523, 645, 771,
+ 703, 264, 773, 300, 299, 301, 776, 302, 778, 319,
+ 313, 315, 316, 321, 344, 317, 333, 362, 728, 220,
+ 382, 199, -461, 199, 326, 752, 199, 523, 388, 523,
+ 213, 735, 503, 345, 365, 387, 389, 392, 305, 747,
+ 214, 416, 16, 197, 18, 417, 418, 419, 436, 221,
+ 435, 435, 751, 244, 453, 446, 455, 435, 457, 426,
+ 456, 462, 466, 469, 476, 568, 569, 470, 480, 481,
+ 483, 484, 487, 762, 327, 764, 488, 490, 489, 191,
+ 491, 793, 508, 492, 539, 513, 636, 38, 527, 493,
+ 543, 328, 495, 514, 496, 517, 552, 780, 515, 204,
+ 518, 205, 787, 528, 789, 551, 790, 558, 559, 561,
+ 562, 786, 435, 206, 207, 557, 565, 799, 208, 574,
+ 801, 575, 636, 636, 592, 497, 576, 566, 577, 582,
+ 581, 757, 220, 810, 583, 584, 588, 591, 220, 597,
+ 601, 602, 54, 760, 209, 604, 763, 610, 603, 611,
+ 613, 220, 615, 620, 435, 769, 519, 642, 643, 665,
+ 651, 636, 329, 636, 636, 636, 636, 652, 657, 655,
+ 63, 64, 668, 675, 693, 696, 698, 322, 711, 199,
+ 199, 712, 724, 211, 727, 212, 732, 734, 746, 330,
+ 748, 749, 750, 755, 758, 765, 467, 770, 772, 777,
+ 779, 808, 15, 781, 658, 199, 199, 563, 663, 795,
+ 364, 688, 503, 697, 431, 811, 788, 802, 761, 511,
+ 199, 199, 199, 199, 731, 213, 807, 660, 805, 783,
+ 407, 406, 411, 413, 414, 214, 307, 303, 449, 743,
+ 415, 544, 266, 343, 343, 767, 621, 435, 744, 267,
+ 647, 507, 599, 268, 269, 270, 271, 272, 273, 274,
+ 376, 275, 460, 371, 412, 372, 228, 0, 0, 276,
+ 0, 0, 0, 0, 277, 0, 0, 278, 0, 0,
+ 0, 0, 325, 0, 220, 435, 279, 0, 0, 0,
+ 0, 0, 199, 0, 0, 0, 220, 0, 759, 220,
+ 0, 0, 280, 0, 0, 745, 0, 0, 220, 0,
+ 0, 0, 0, 0, 0, 325, 0, 11, 0, 12,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 0,
+ 0, 25, 0, 0, 0, 0, 26, 27, 28, 0,
+ 29, 199, 0, 0, 30, 0, 0, 798, 31, 0,
+ 766, 0, 32, 33, 0, 0, 0, 0, 34, 0,
+ 35, 36, 0, 0, 37, 38, 39, 40, 41, 42,
+ 0, 0, 0, 0, 0, 0, 0, 43, 0, 0,
+ 44, 45, 0, 0, 46, 0, 0, 0, 0, 0,
+ 0, 47, 0, 0, 0, 0, 48, 49, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 50, 51,
+ 0, 0, 0, 52, 0, 0, 0, 0, 53, 0,
+ 54, 0, 0, 0, 0, 55, 0, 0, 0, 56,
+ 57, 58, 0, 0, 59, 0, 60, 61, 0, 0,
+ 62, 0, 0, 0, 0, 0, 0, 0, 63, 64,
+ 0, 65, 0, 66, 67, 68, 0, 0, 69, 0,
+ 0, 0, 0, 0, 0, 70, 0, 71, 0, 0,
+ 0, 0, 72, 0, 73, 74, 0, 0, 0, 0,
+ 0, 75, 76, 11, 0, 12, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 0, 0, 25, 0, 0,
+ 0, 0, 26, 27, 28, 0, 29, 0, 0, 0,
+ 30, 0, 0, 0, 31, 0, 0, 0, 32, 33,
+ 0, 0, 0, 0, 233, 0, 35, 36, 0, 0,
+ 37, 38, 39, 40, 41, 42, 0, 0, 0, 0,
+ 0, 0, 0, 43, 0, 0, 44, 45, 0, 0,
+ 46, 0, 0, 0, 0, 0, 0, 47, 0, 0,
+ 0, 0, 48, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 50, 51, 0, 0, 0, 52,
+ 0, 0, 0, 0, 53, 0, 54, 0, 0, 0,
+ 0, 55, 0, 0, 0, 56, 57, 58, 0, 0,
+ 59, 0, 60, 61, 0, 0, 62, 0, 0, 0,
+ 0, 0, 234, 0, 63, 64, 0, 65, 0, 66,
+ 67, 68, 0, 0, 69, 0, 0, 0, 0, 0,
+ 0, 70, 0, 71, 0, 0, 0, 0, 72, 0,
+ 73, 74, 0, 0, 0, 0, 0, 75, 76, 11,
+ 0, 12, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 0, 0, 25, 0, 0, 0, 0, 26, 27,
+ 28, 0, 29, 0, 0, 0, 30, 0, 0, 0,
+ 31, 0, 0, 0, 32, 33, 0, 0, 0, 420,
+ 233, 0, 35, 36, 0, 0, 37, 38, 39, 40,
+ 41, 42, 0, 0, 0, 0, 0, 0, 0, 43,
+ 0, 0, 44, 45, 0, 0, 46, 0, 0, 0,
+ 0, 0, 0, 47, 0, 0, 0, 0, 48, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 50, 51, 0, 0, 0, 52, 0, 0, 0, 0,
+ 53, 0, 54, 0, 0, 0, 0, 55, 0, 0,
+ 0, 56, 57, 58, 0, 0, 59, 0, 60, 61,
+ 0, 0, 62, 0, 0, 0, 0, 0, 0, 0,
+ 63, 64, 0, 65, 0, 66, 67, 68, 0, 0,
+ 69, 0, 0, 0, 0, 0, 0, 70, 0, 71,
+ 0, 0, 0, 0, 72, 0, 73, 74, 0, 0,
+ 0, 0, 0, 75, 76, 11, 0, 12, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 0, 0, 25,
+ 0, 0, 0, 0, 26, 27, 28, 0, 29, 0,
+ 0, 0, 30, 0, 0, 0, 31, 0, 0, 0,
+ 32, 33, 0, 0, 0, 0, 233, 0, 35, 36,
+ 0, 0, 37, 38, 39, 40, 41, 42, 0, 0,
+ 0, 0, 0, 0, 0, 43, 0, 0, 44, 45,
+ 0, 0, 46, 0, 0, 0, 0, 0, 0, 47,
+ 0, 0, 0, 0, 48, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 50, 51, 0, 0,
+ 0, 52, 0, 0, 0, 0, 53, 0, 54, 0,
+ 0, 0, 0, 55, 0, 0, 0, 56, 57, 58,
+ 0, 0, 59, 0, 60, 61, 0, 0, 62, 0,
+ 0, 0, 0, 0, 0, 0, 63, 64, 0, 65,
+ 0, 66, 67, 68, 0, 0, 69, 0, 0, 0,
+ 0, 0, 0, 70, 0, 71, 0, 0, 0, 0,
+ 72, 0, 73, 74, 0, 0, 0, 0, 0, 75,
+ 76, 11, 0, 12, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 0, 0, 25, 0, 0, 0, 0,
+ 26, 27, 0, 0, 29, 0, 0, 0, 30, 0,
+ 0, 0, 31, 0, 0, 0, 32, 33, 0, 0,
+ 0, 0, 233, 0, 35, 36, 0, 0, 37, 38,
+ 39, 40, 41, 42, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 44, 45, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 47, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 51, 0, 0, 0, 52, 0, 0,
+ 0, 0, 53, 0, 54, 0, 0, 0, 0, 55,
+ 0, 0, 0, 56, 57, 58, 0, 0, 59, 0,
+ 60, 61, 0, 0, 62, 0, 0, 0, 0, 0,
+ 0, 0, 63, 64, 0, 65, 0, 66, 67, 0,
+ 0, 0, 69, 0, 0, 0, 0, 0, 0, 70,
+ 0, 71, 0, 0, 0, 0, 0, 0, 73, 74,
+ 0, 0, 0, 0, 0, 75, 76, 11, 0, 12,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 0,
+ 0, 25, 0, 0, 0, 0, 26, 27, 0, 0,
+ 29, 0, 0, 0, 30, 0, 0, 0, 31, 0,
+ 0, 0, 32, 33, 0, 0, 0, 0, 233, 0,
+ 35, 36, 0, 0, 37, 38, 39, 40, 41, 42,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 44, 45, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 53, 0,
+ 54, 0, 0, 0, 0, 55, 0, 0, 0, 56,
+ 57, 0, 0, 0, 0, 0, 60, 61, 0, 0,
+ 62, 0, 0, 0, 0, 0, 0, 0, 63, 64,
+ 0, 65, 0, 0, 0, 0, 423, 0, 69, 0,
+ 0, 0, 0, 0, 0, 70, 0, 71, 0, 0,
+ 0, 0, 0, 0, 73, 0, 0, 0, 0, 0,
+ 0, 75, 76, 11, 0, 12, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 0, 0, 25, 0, 0,
+ 0, 0, 26, 27, 0, 0, 29, 0, 0, 0,
+ 30, 0, 0, 0, 31, 0, 0, 0, 32, 33,
+ 0, 0, 0, 0, 233, 0, 35, 36, 0, 0,
+ 37, 38, 39, 40, 41, 42, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 44, 45, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 0, 0,
+ 16, 17, 18, 19, 20, 0, 0, 23, 24, 0,
+ 0, 0, 0, 0, 0, 51, 26, 628, 0, 0,
+ 0, 0, 0, 0, 53, 0, 54, 0, 31, 0,
+ 0, 55, 327, 0, 0, 56, 57, 0, 0, 0,
+ 35, 36, 60, 61, 0, 38, 62, 0, 41, 328,
+ 0, 0, 0, 0, 63, 64, 0, 65, 0, 0,
+ 44, 45, 0, 0, 69, 0, 0, 0, 0, 0,
+ 0, 70, 0, 71, 0, 0, 0, 0, 0, 0,
+ 73, 16, 197, 18, 19, 20, 0, 75, 76, 0,
+ 0, 0, 0, 0, 0, 16, 197, 18, 19, 20,
+ 54, 0, 23, 24, 0, 0, 0, 0, 0, 56,
+ 0, 26, 628, 327, 0, 0, 60, 61, 0, 0,
+ 329, 0, 0, 31, 0, 0, 38, 327, 63, 64,
+ 328, 65, 0, 629, 630, 35, 36, 0, 69, 0,
+ 38, 0, 0, 41, 328, 0, 0, 330, 0, 0,
+ 0, 0, 0, 0, 0, 44, 45, 0, 0, 0,
+ 0, 75, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 0, 0,
+ 0, 329, 0, 0, 56, 0, 0, 0, 0, 0,
+ 64, 60, 61, 0, 0, 329, 0, 0, 0, 69,
+ 0, 0, 0, 63, 64, 0, 65, 0, 330, 0,
+ 0, 0, 0, 69, 0, 0, 0, 0, 0, 0,
+ 0, 0, 330
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 30, 246, 53, 25, 51, 417, 30, 262, 263, 39,
+ 314, 62, 35, 321, 341, 190, 343, 311, 312, 4,
+ 687, 32, 416, 417, 36, 76, 3, 38, 5, 59,
+ 7, 42, 6, 7, 8, 32, 87, 37, 379, 347,
+ 37, 224, 225, 54, 29, 42, 52, 37, 37, 16,
+ 52, 62, 709, 50, 90, 593, 35, 95, 111, 400,
+ 71, 55, 317, 45, 476, 350, 20, 686, 353, 252,
+ 6, 7, 8, 49, 71, 383, 55, 128, 386, 364,
+ 70, 19, 476, 95, 37, 6, 7, 8, 37, 37,
+ 709, 732, 71, 338, 95, 79, 64, 98, 6, 7,
+ 37, 42, 165, 686, 94, 81, 37, 160, 92, 145,
+ 48, 65, 416, 417, 6, 7, 8, 9, 10, 87,
+ 37, 37, 104, 113, 765, 101, 709, 468, 166, 131,
+ 668, 23, 132, 70, 113, 163, 803, 159, 132, 314,
+ 7, 135, 193, 166, 133, 486, 38, 455, 456, 434,
+ 201, 157, 809, 143, 166, 132, 31, 94, 188, 51,
+ 190, 191, 129, 55, 215, 450, 95, 75, 144, 454,
+ 45, 222, 476, 458, 164, 42, 113, 796, 463, 120,
+ 133, 211, 229, 132, 132, 0, 237, 211, 102, 236,
+ 809, 221, 222, 167, 224, 225, 132, 221, 222, 184,
+ 44, 132, 253, 254, 387, 546, 143, 204, 144, 256,
+ 195, 132, 209, 796, 106, 132, 132, 214, 248, 249,
+ 128, 104, 252, 144, 248, 249, 809, 164, 95, 3,
+ 475, 5, 629, 630, 126, 69, 102, 166, 117, 83,
+ 59, 84, 134, 135, 656, 6, 7, 532, 127, 534,
+ 535, 559, 144, 3, 4, 5, 241, 512, 305, 244,
+ 7, 153, 656, 97, 107, 144, 313, 99, 42, 316,
+ 136, 441, 99, 670, 671, 560, 42, 27, 563, 139,
+ 140, 622, 623, 577, 314, 117, 469, 139, 140, 39,
+ 117, 124, 42, 6, 7, 8, 551, 344, 124, 65,
+ 545, 471, 557, 473, 113, 139, 140, 592, 95, 339,
+ 595, 566, 100, 146, 108, 339, 327, 328, 329, 330,
+ 146, 648, 649, 664, 26, 95, 28, 77, 155, 42,
+ 124, 361, 672, 673, 143, 365, 321, 148, 40, 41,
+ 3, 365, 5, 45, 652, 66, 67, 602, 6, 7,
+ 8, 3, 656, 5, 166, 610, 341, 387, 343, 6,
+ 7, 8, 347, 418, 419, 620, 116, 95, 52, 71,
+ 52, 95, 357, 6, 7, 8, 42, 95, 363, 6,
+ 7, 8, 690, 150, 639, 95, 416, 417, 418, 419,
+ 95, 676, 416, 417, 418, 419, 651, 52, 383, 582,
+ 95, 386, 104, 7, 15, 588, 37, 37, 110, 439,
+ 112, 441, 281, 282, 283, 439, 757, 441, 601, 760,
+ 675, 114, 763, 156, 86, 32, 767, 33, 769, 138,
+ 91, 36, 91, 73, 42, 95, 132, 7, 693, 469,
+ 104, 471, 95, 473, 95, 730, 476, 471, 104, 473,
+ 152, 706, 476, 95, 103, 52, 132, 149, 42, 714,
+ 162, 109, 6, 7, 8, 18, 18, 18, 7, 95,
+ 455, 456, 727, 95, 37, 132, 104, 462, 57, 23,
+ 104, 73, 98, 52, 18, 496, 497, 132, 132, 7,
+ 55, 7, 7, 748, 38, 750, 43, 132, 119, 95,
+ 132, 786, 43, 132, 95, 130, 593, 51, 43, 132,
+ 95, 55, 132, 130, 58, 73, 21, 772, 132, 26,
+ 132, 28, 777, 132, 779, 85, 781, 73, 21, 104,
+ 73, 776, 517, 40, 41, 154, 73, 792, 45, 127,
+ 795, 29, 629, 630, 541, 89, 113, 85, 131, 52,
+ 37, 734, 582, 808, 132, 132, 52, 42, 588, 127,
+ 52, 85, 106, 746, 71, 73, 749, 20, 118, 3,
+ 31, 601, 29, 37, 559, 758, 157, 132, 132, 626,
+ 56, 668, 126, 670, 671, 672, 673, 37, 60, 52,
+ 134, 135, 25, 20, 20, 43, 132, 104, 16, 629,
+ 630, 129, 18, 110, 35, 112, 100, 52, 52, 153,
+ 131, 52, 131, 125, 52, 37, 95, 75, 131, 85,
+ 20, 131, 9, 85, 619, 655, 656, 485, 624, 85,
+ 212, 655, 656, 668, 317, 809, 778, 796, 747, 423,
+ 670, 671, 672, 673, 695, 152, 803, 620, 800, 774,
+ 265, 264, 286, 292, 295, 162, 130, 122, 345, 710,
+ 298, 467, 61, 648, 649, 756, 581, 652, 710, 68,
+ 603, 419, 548, 72, 73, 74, 75, 76, 77, 78,
+ 222, 80, 361, 216, 287, 216, 47, -1, -1, 88,
+ -1, -1, -1, -1, 93, -1, -1, 96, -1, -1,
+ -1, -1, 732, -1, 734, 690, 105, -1, -1, -1,
+ -1, -1, 742, -1, -1, -1, 746, -1, 742, 749,
+ -1, -1, 121, -1, -1, 710, -1, -1, 758, -1,
+ -1, -1, -1, -1, -1, 765, -1, 3, -1, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, -1,
+ -1, 17, -1, -1, -1, -1, 22, 23, 24, -1,
+ 26, 791, -1, -1, 30, -1, -1, 791, 34, -1,
+ 755, -1, 38, 39, -1, -1, -1, -1, 44, -1,
+ 46, 47, -1, -1, 50, 51, 52, 53, 54, 55,
+ -1, -1, -1, -1, -1, -1, -1, 63, -1, -1,
+ 66, 67, -1, -1, 70, -1, -1, -1, -1, -1,
+ -1, 77, -1, -1, -1, -1, 82, 83, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 94, 95,
+ -1, -1, -1, 99, -1, -1, -1, -1, 104, -1,
+ 106, -1, -1, -1, -1, 111, -1, -1, -1, 115,
+ 116, 117, -1, -1, 120, -1, 122, 123, -1, -1,
+ 126, -1, -1, -1, -1, -1, -1, -1, 134, 135,
+ -1, 137, -1, 139, 140, 141, -1, -1, 144, -1,
+ -1, -1, -1, -1, -1, 151, -1, 153, -1, -1,
+ -1, -1, 158, -1, 160, 161, -1, -1, -1, -1,
+ -1, 167, 168, 3, -1, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, -1, 17, -1, -1,
+ -1, -1, 22, 23, 24, -1, 26, -1, -1, -1,
+ 30, -1, -1, -1, 34, -1, -1, -1, 38, 39,
+ -1, -1, -1, -1, 44, -1, 46, 47, -1, -1,
+ 50, 51, 52, 53, 54, 55, -1, -1, -1, -1,
+ -1, -1, -1, 63, -1, -1, 66, 67, -1, -1,
+ 70, -1, -1, -1, -1, -1, -1, 77, -1, -1,
+ -1, -1, 82, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 94, 95, -1, -1, -1, 99,
+ -1, -1, -1, -1, 104, -1, 106, -1, -1, -1,
+ -1, 111, -1, -1, -1, 115, 116, 117, -1, -1,
+ 120, -1, 122, 123, -1, -1, 126, -1, -1, -1,
+ -1, -1, 132, -1, 134, 135, -1, 137, -1, 139,
+ 140, 141, -1, -1, 144, -1, -1, -1, -1, -1,
+ -1, 151, -1, 153, -1, -1, -1, -1, 158, -1,
+ 160, 161, -1, -1, -1, -1, -1, 167, 168, 3,
+ -1, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, -1, -1, 17, -1, -1, -1, -1, 22, 23,
+ 24, -1, 26, -1, -1, -1, 30, -1, -1, -1,
+ 34, -1, -1, -1, 38, 39, -1, -1, -1, 43,
+ 44, -1, 46, 47, -1, -1, 50, 51, 52, 53,
+ 54, 55, -1, -1, -1, -1, -1, -1, -1, 63,
+ -1, -1, 66, 67, -1, -1, 70, -1, -1, -1,
+ -1, -1, -1, 77, -1, -1, -1, -1, 82, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 94, 95, -1, -1, -1, 99, -1, -1, -1, -1,
+ 104, -1, 106, -1, -1, -1, -1, 111, -1, -1,
+ -1, 115, 116, 117, -1, -1, 120, -1, 122, 123,
+ -1, -1, 126, -1, -1, -1, -1, -1, -1, -1,
+ 134, 135, -1, 137, -1, 139, 140, 141, -1, -1,
+ 144, -1, -1, -1, -1, -1, -1, 151, -1, 153,
+ -1, -1, -1, -1, 158, -1, 160, 161, -1, -1,
+ -1, -1, -1, 167, 168, 3, -1, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, -1, -1, 17,
+ -1, -1, -1, -1, 22, 23, 24, -1, 26, -1,
+ -1, -1, 30, -1, -1, -1, 34, -1, -1, -1,
+ 38, 39, -1, -1, -1, -1, 44, -1, 46, 47,
+ -1, -1, 50, 51, 52, 53, 54, 55, -1, -1,
+ -1, -1, -1, -1, -1, 63, -1, -1, 66, 67,
+ -1, -1, 70, -1, -1, -1, -1, -1, -1, 77,
+ -1, -1, -1, -1, 82, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 94, 95, -1, -1,
+ -1, 99, -1, -1, -1, -1, 104, -1, 106, -1,
+ -1, -1, -1, 111, -1, -1, -1, 115, 116, 117,
+ -1, -1, 120, -1, 122, 123, -1, -1, 126, -1,
+ -1, -1, -1, -1, -1, -1, 134, 135, -1, 137,
+ -1, 139, 140, 141, -1, -1, 144, -1, -1, -1,
+ -1, -1, -1, 151, -1, 153, -1, -1, -1, -1,
+ 158, -1, 160, 161, -1, -1, -1, -1, -1, 167,
+ 168, 3, -1, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, -1, -1, 17, -1, -1, -1, -1,
+ 22, 23, -1, -1, 26, -1, -1, -1, 30, -1,
+ -1, -1, 34, -1, -1, -1, 38, 39, -1, -1,
+ -1, -1, 44, -1, 46, 47, -1, -1, 50, 51,
+ 52, 53, 54, 55, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 66, 67, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 77, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 95, -1, -1, -1, 99, -1, -1,
+ -1, -1, 104, -1, 106, -1, -1, -1, -1, 111,
+ -1, -1, -1, 115, 116, 117, -1, -1, 120, -1,
+ 122, 123, -1, -1, 126, -1, -1, -1, -1, -1,
+ -1, -1, 134, 135, -1, 137, -1, 139, 140, -1,
+ -1, -1, 144, -1, -1, -1, -1, -1, -1, 151,
+ -1, 153, -1, -1, -1, -1, -1, -1, 160, 161,
+ -1, -1, -1, -1, -1, 167, 168, 3, -1, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, -1,
+ -1, 17, -1, -1, -1, -1, 22, 23, -1, -1,
+ 26, -1, -1, -1, 30, -1, -1, -1, 34, -1,
+ -1, -1, 38, 39, -1, -1, -1, -1, 44, -1,
+ 46, 47, -1, -1, 50, 51, 52, 53, 54, 55,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 66, 67, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 77, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 95,
+ -1, -1, -1, -1, -1, -1, -1, -1, 104, -1,
+ 106, -1, -1, -1, -1, 111, -1, -1, -1, 115,
+ 116, -1, -1, -1, -1, -1, 122, 123, -1, -1,
+ 126, -1, -1, -1, -1, -1, -1, -1, 134, 135,
+ -1, 137, -1, -1, -1, -1, 142, -1, 144, -1,
+ -1, -1, -1, -1, -1, 151, -1, 153, -1, -1,
+ -1, -1, -1, -1, 160, -1, -1, -1, -1, -1,
+ -1, 167, 168, 3, -1, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, -1, 17, -1, -1,
+ -1, -1, 22, 23, -1, -1, 26, -1, -1, -1,
+ 30, -1, -1, -1, 34, -1, -1, -1, 38, 39,
+ -1, -1, -1, -1, 44, -1, 46, 47, -1, -1,
+ 50, 51, 52, 53, 54, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 67, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 77, -1, -1,
+ 6, 7, 8, 9, 10, -1, -1, 13, 14, -1,
+ -1, -1, -1, -1, -1, 95, 22, 23, -1, -1,
+ -1, -1, -1, -1, 104, -1, 106, -1, 34, -1,
+ -1, 111, 38, -1, -1, 115, 116, -1, -1, -1,
+ 46, 47, 122, 123, -1, 51, 126, -1, 54, 55,
+ -1, -1, -1, -1, 134, 135, -1, 137, -1, -1,
+ 66, 67, -1, -1, 144, -1, -1, -1, -1, -1,
+ -1, 151, -1, 153, -1, -1, -1, -1, -1, -1,
+ 160, 6, 7, 8, 9, 10, -1, 167, 168, -1,
+ -1, -1, -1, -1, -1, 6, 7, 8, 9, 10,
+ 106, -1, 13, 14, -1, -1, -1, -1, -1, 115,
+ -1, 22, 23, 38, -1, -1, 122, 123, -1, -1,
+ 126, -1, -1, 34, -1, -1, 51, 38, 134, 135,
+ 55, 137, -1, 139, 140, 46, 47, -1, 144, -1,
+ 51, -1, -1, 54, 55, -1, -1, 153, -1, -1,
+ -1, -1, -1, -1, -1, 66, 67, -1, -1, -1,
+ -1, 167, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 106, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 106, -1, -1, -1, -1,
+ -1, 126, -1, -1, 115, -1, -1, -1, -1, -1,
+ 135, 122, 123, -1, -1, 126, -1, -1, -1, 144,
+ -1, -1, -1, 134, 135, -1, 137, -1, 153, -1,
+ -1, -1, -1, 144, -1, -1, -1, -1, -1, -1,
+ -1, -1, 153
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint16 yystos[] =
+{
+ 0, 165, 170, 171, 163, 0, 102, 173, 174, 175,
+ 176, 3, 5, 404, 104, 176, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 17, 22, 23, 24, 26,
+ 30, 34, 38, 39, 44, 46, 47, 50, 51, 52,
+ 53, 54, 55, 63, 66, 67, 70, 77, 82, 83,
+ 94, 95, 99, 104, 106, 111, 115, 116, 117, 120,
+ 122, 123, 126, 134, 135, 137, 139, 140, 141, 144,
+ 151, 153, 158, 160, 161, 167, 168, 177, 183, 184,
+ 186, 187, 189, 190, 191, 192, 193, 194, 195, 197,
+ 200, 201, 202, 204, 208, 211, 213, 219, 225, 226,
+ 227, 232, 233, 240, 253, 254, 260, 267, 276, 277,
+ 278, 279, 280, 281, 283, 285, 286, 289, 290, 291,
+ 292, 293, 294, 295, 296, 298, 300, 302, 303, 304,
+ 306, 307, 309, 310, 311, 322, 323, 324, 327, 328,
+ 329, 331, 332, 333, 334, 335, 336, 337, 338, 339,
+ 340, 342, 343, 344, 345, 347, 348, 349, 358, 359,
+ 360, 361, 362, 365, 366, 367, 368, 375, 382, 383,
+ 384, 386, 387, 388, 389, 390, 391, 392, 394, 397,
+ 399, 400, 404, 405, 59, 172, 7, 44, 100, 229,
+ 330, 95, 166, 364, 395, 95, 404, 7, 397, 405,
+ 95, 364, 395, 148, 26, 28, 40, 41, 45, 71,
+ 104, 110, 112, 152, 162, 364, 95, 395, 7, 341,
+ 405, 95, 364, 395, 52, 52, 6, 7, 401, 95,
+ 102, 136, 364, 44, 132, 225, 42, 218, 395, 150,
+ 7, 402, 405, 7, 95, 218, 374, 395, 95, 95,
+ 310, 310, 52, 312, 364, 395, 95, 90, 145, 7,
+ 218, 218, 37, 37, 114, 15, 61, 68, 72, 73,
+ 74, 75, 76, 77, 78, 80, 88, 93, 96, 105,
+ 121, 297, 299, 301, 99, 117, 155, 282, 49, 81,
+ 101, 144, 284, 25, 159, 287, 64, 87, 288, 86,
+ 156, 32, 33, 293, 218, 42, 305, 307, 69, 97,
+ 139, 140, 321, 91, 325, 36, 91, 95, 404, 138,
+ 185, 73, 104, 7, 231, 405, 95, 38, 55, 126,
+ 153, 333, 7, 132, 144, 396, 405, 218, 369, 370,
+ 373, 218, 356, 404, 42, 95, 218, 364, 124, 146,
+ 188, 124, 146, 212, 108, 124, 198, 35, 55, 71,
+ 113, 364, 7, 397, 194, 103, 181, 182, 364, 218,
+ 385, 392, 394, 144, 397, 372, 373, 397, 341, 341,
+ 350, 225, 104, 205, 45, 104, 203, 52, 104, 132,
+ 225, 218, 149, 308, 404, 7, 404, 305, 397, 397,
+ 341, 218, 218, 225, 227, 227, 278, 279, 280, 280,
+ 280, 281, 283, 285, 286, 289, 109, 18, 18, 18,
+ 43, 225, 311, 142, 311, 225, 23, 326, 333, 389,
+ 225, 226, 227, 346, 403, 404, 7, 314, 315, 37,
+ 132, 37, 132, 305, 397, 356, 132, 356, 225, 314,
+ 403, 185, 185, 37, 404, 104, 104, 57, 196, 7,
+ 399, 405, 73, 404, 185, 397, 98, 95, 317, 52,
+ 132, 37, 132, 37, 132, 363, 18, 377, 377, 353,
+ 132, 7, 403, 55, 7, 403, 341, 7, 43, 119,
+ 132, 132, 132, 132, 377, 132, 58, 89, 378, 380,
+ 381, 382, 389, 397, 378, 376, 381, 376, 43, 113,
+ 143, 246, 252, 130, 130, 132, 185, 73, 132, 157,
+ 316, 318, 319, 397, 398, 398, 371, 43, 132, 185,
+ 84, 107, 199, 185, 403, 403, 79, 92, 185, 95,
+ 3, 403, 185, 95, 316, 377, 341, 398, 398, 305,
+ 378, 85, 21, 239, 351, 354, 401, 154, 73, 21,
+ 206, 104, 73, 206, 377, 73, 85, 268, 395, 395,
+ 117, 127, 144, 379, 127, 29, 113, 131, 227, 247,
+ 248, 37, 52, 132, 132, 185, 185, 185, 52, 215,
+ 216, 42, 364, 178, 132, 305, 377, 127, 393, 393,
+ 227, 52, 85, 118, 73, 227, 207, 403, 185, 185,
+ 20, 3, 227, 31, 269, 29, 311, 19, 48, 249,
+ 37, 318, 341, 341, 37, 132, 313, 185, 23, 139,
+ 140, 220, 221, 222, 223, 224, 322, 345, 185, 20,
+ 65, 209, 132, 132, 261, 341, 227, 353, 16, 129,
+ 355, 56, 37, 227, 255, 52, 273, 60, 196, 250,
+ 248, 377, 377, 216, 214, 225, 223, 223, 25, 179,
+ 139, 140, 139, 140, 227, 20, 210, 262, 234, 75,
+ 128, 352, 356, 356, 227, 403, 241, 256, 397, 378,
+ 35, 166, 251, 20, 320, 377, 43, 221, 132, 223,
+ 223, 224, 224, 227, 185, 37, 133, 263, 266, 235,
+ 357, 16, 129, 37, 164, 233, 240, 242, 244, 245,
+ 246, 37, 257, 266, 18, 270, 403, 35, 227, 65,
+ 217, 218, 100, 228, 52, 227, 37, 233, 236, 240,
+ 244, 4, 27, 218, 348, 404, 52, 227, 131, 52,
+ 131, 227, 185, 230, 231, 125, 180, 341, 52, 397,
+ 341, 245, 227, 341, 227, 37, 404, 317, 377, 341,
+ 75, 377, 131, 377, 271, 231, 377, 85, 377, 20,
+ 227, 85, 45, 269, 272, 274, 305, 227, 239, 227,
+ 227, 52, 131, 185, 264, 85, 243, 258, 397, 227,
+ 265, 227, 242, 259, 275, 263, 237, 257, 131, 238,
+ 227, 236
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, parseInfo, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, parseInfo)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location, parseInfo); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ParserContext *const parseInfo)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parseInfo)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ ParserContext *const parseInfo;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+ YYUSE (parseInfo);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ParserContext *const parseInfo)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parseInfo)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ ParserContext *const parseInfo;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parseInfo);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, ParserContext *const parseInfo)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, parseInfo)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+ ParserContext *const parseInfo;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) , parseInfo);
+ fprintf (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule, parseInfo); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, ParserContext *const parseInfo)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, parseInfo)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+ ParserContext *const parseInfo;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ YYUSE (parseInfo);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (ParserContext *const parseInfo);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (ParserContext *const parseInfo)
+#else
+int
+yyparse (parseInfo)
+ ParserContext *const parseInfo;
+#endif
+#endif
+{
+ /* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc;
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[2];
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+ yylsp = yyls;
+#if YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+ YYSTACK_RELOCATE (yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 5:
+/* Line 1269 of yacc.c. */
+#line 1380 "querytransformparser.ypp"
+ {
+
+/* Suppress more compiler warnings about unused defines. */
+#if defined(YYNNTS) \
+ || defined(yyerrok) \
+ || defined(YYNSTATES) \
+ || defined(YYRHSLOC) \
+ || defined(YYRECOVERING) \
+ || defined(YYFAIL) \
+ || defined(YYERROR) \
+ || defined(YYNRULES) \
+ || defined(YYBACKUP) \
+ || defined(YYMAXDEPTH) \
+ || defined(yyclearin) \
+ || defined(YYERRCODE) \
+ || defined(YY_LOCATION_PRINT) \
+ || defined(YYLLOC_DEFAULT)
+#endif
+
+ if((yyvsp[(3) - (5)].sval) != QLatin1String("1.0"))
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Version %1 is not supported. The supported "
+ "XQuery version is 1.0.")
+ .arg(formatData((yyvsp[(3) - (5)].sval))),
+ ReportContext::XQST0031, &ryy);
+ }
+ }
+ break;
+
+ case 7:
+/* Line 1269 of yacc.c. */
+#line 1412 "querytransformparser.ypp"
+ {
+ const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));
+
+ if(!encNameRegExp.exactMatch((yyvsp[(2) - (2)].sval)))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The encoding %1 is invalid. "
+ "It must contain Latin characters only, "
+ "must not contain whitespace, and must match "
+ "the regular expression %2.")
+ .arg(formatKeyword((yyvsp[(2) - (2)].sval)),
+ formatExpression(encNameRegExp.pattern())),
+ ReportContext::XQST0087, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 8:
+/* Line 1269 of yacc.c. */
+#line 1428 "querytransformparser.ypp"
+ {
+ /* In XSL-T, we can have dangling variable references, so resolve them
+ * before we proceed with other steps, such as checking circularity. */
+ if(parseInfo->isXSLT())
+ {
+ typedef QHash<QXmlName, Expression::Ptr> Hash;
+ const Hash::const_iterator end(parseInfo->unresolvedVariableReferences.constEnd());
+
+ for(Hash::const_iterator it(parseInfo->unresolvedVariableReferences.constBegin()); it != end; ++it)
+ {
+ const Expression::Ptr body(resolveVariable(it.key(), (yyloc), parseInfo, true)); // TODO source locations vaise
+ Q_ASSERT(body);
+ it.value()->as<UnresolvedVariableReference>()->bindTo(body);
+ }
+ }
+
+ /* The UserFunction callsites aren't bound yet, so bind them(if possible!). */
+ {
+ const UserFunctionCallsite::List::const_iterator cend(parseInfo->userFunctionCallsites.constEnd());
+ UserFunctionCallsite::List::const_iterator cit(parseInfo->userFunctionCallsites.constBegin());
+ for(; cit != cend; ++cit) /* For each callsite. */
+ {
+ const UserFunctionCallsite::Ptr callsite(*cit);
+ Q_ASSERT(callsite);
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it) /* For each UserFunction. */
+ {
+ const FunctionSignature::Ptr sign((*it)->signature());
+ Q_ASSERT(sign);
+
+ if(callsite->isSignatureValid(sign))
+ {
+ callsite->setSource((*it),
+ parseInfo->allocateCacheSlots((*it)->argumentDeclarations().count()));
+ break;
+ }
+ }
+ if(it == end)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function with signature %1 is available")
+ .arg(formatFunction(callsite)),
+ ReportContext::XPST0017, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ }
+
+ /* Mark callsites in UserFunction bodies as recursive, if they are. */
+ {
+ const UserFunction::List::const_iterator fend(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator fit(parseInfo->userFunctions.constBegin());
+ for(; fit != fend; ++fit)
+ {
+ CallTargetDescription::List signList;
+ signList.append((*fit)->signature());
+ CallTargetDescription::checkCallsiteCircularity(signList, (*fit)->body());
+ }
+ }
+
+ /* Now, check all global variables for circularity. This is done
+ * backwards because global variables are only in scope below them,
+ * in XQuery. */
+ {
+ const VariableDeclaration::List::const_iterator start(parseInfo->declaredVariables.constBegin());
+ VariableDeclaration::List::const_iterator it(parseInfo->declaredVariables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ if((*it)->type != VariableDeclaration::ExpressionVariable && (*it)->type != VariableDeclaration::GlobalVariable)
+ continue; /* We want to ignore 'external' variables. */
+
+ FunctionSignature::List signList;
+ checkVariableCircularity(*it, (*it)->expression(), (*it)->type, signList, parseInfo);
+ ExpressionFactory::registerLastPath((*it)->expression());
+ parseInfo->finalizePushedVariable(1, false); /* Warn if it's unused. */
+ }
+ }
+
+ /* Generate code for doing initial template name calling. One problem
+ * is that we compilation in the initial template name, since we throw away the
+ * code if we don't have the requested template. */
+ if(parseInfo->languageAccent == QXmlQuery::XSLT20
+ && !parseInfo->initialTemplateName.isNull()
+ && parseInfo->namedTemplates.contains(parseInfo->initialTemplateName))
+ {
+ parseInfo->queryBody = create(new CallTemplate(parseInfo->initialTemplateName,
+ WithParam::Hash()),
+ (yyloc), parseInfo);
+ parseInfo->templateCalls.append(parseInfo->queryBody);
+ /* We just discard the template body that XSLTTokenizer generated. */
+ }
+ else
+ parseInfo->queryBody = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 10:
+/* Line 1269 of yacc.c. */
+#line 1528 "querytransformparser.ypp"
+ {
+ // TODO add to namespace context
+ parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(3) - (6)].sval));
+ }
+ break;
+
+ case 12:
+/* Line 1269 of yacc.c. */
+#line 1536 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 13:
+/* Line 1269 of yacc.c. */
+#line 1543 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 14:
+/* Line 1269 of yacc.c. */
+#line 1549 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace declarations must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 15:
+/* Line 1269 of yacc.c. */
+#line 1555 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 17:
+/* Line 1269 of yacc.c. */
+#line 1565 "querytransformparser.ypp"
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 18:
+/* Line 1269 of yacc.c. */
+#line 1569 "querytransformparser.ypp"
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 19:
+/* Line 1269 of yacc.c. */
+#line 1573 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 20:
+/* Line 1269 of yacc.c. */
+#line 1596 "querytransformparser.ypp"
+ {
+ Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, (yyvsp[(5) - (7)].sequenceType)), (yyloc), parseInfo));
+
+ registerNamedTemplate((yyvsp[(3) - (7)].qName), typeCheckTemplateBody((yyvsp[(6) - (7)].expr), (yyvsp[(5) - (7)].sequenceType), parseInfo),
+ parseInfo, (yylsp[(1) - (7)]), temp);
+ temp->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+ }
+ break;
+
+ case 21:
+/* Line 1269 of yacc.c. */
+#line 1606 "querytransformparser.ypp"
+ {
+ parseInfo->isParsingPattern = true;
+ }
+ break;
+
+ case 22:
+/* Line 1269 of yacc.c. */
+#line 1610 "querytransformparser.ypp"
+ {
+ parseInfo->isParsingPattern = false;
+ }
+ break;
+
+ case 23:
+/* Line 1269 of yacc.c. */
+#line 1619 "querytransformparser.ypp"
+ {
+ /* In this grammar branch, we're guaranteed to be a template rule, but
+ * may also be a named template. */
+
+ const ImportPrecedence ip = parseInfo->isFirstTemplate() ? 0 : parseInfo->currentImportPrecedence;
+ Expression::Ptr pattern((yyvsp[(7) - (15)].expr));
+ const TemplatePattern::ID templateID = parseInfo->allocateTemplateID();
+
+ Template::Ptr templ(create(new Template(ip, (yyvsp[(13) - (15)].sequenceType)), (yyloc), parseInfo));
+ templ->body = typeCheckTemplateBody((yyvsp[(14) - (15)].expr), (yyvsp[(13) - (15)].sequenceType), parseInfo);
+ templ->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+
+ TemplatePattern::Vector ourPatterns;
+ /* We do it as per 6.4 Conflict Resolution for Template Rules:
+ *
+ * "If the pattern contains multiple alternatives separated by |, then
+ * the template rule is treated equivalently to a set of template
+ * rules, one for each alternative. However, it is not an error if a
+ * node matches more than one of the alternatives." */
+ while(pattern->is(Expression::IDCombineNodes))
+ {
+ const Expression::List operands(pattern->operands());
+ pattern = operands.first();
+
+ loadPattern(operands.at(1), ourPatterns, templateID, (yyvsp[(11) - (15)].enums.Double), templ);
+ }
+
+ loadPattern(pattern, ourPatterns, templateID, (yyvsp[(11) - (15)].enums.Double), templ);
+
+ if(!(yyvsp[(3) - (15)].qName).isNull())
+ registerNamedTemplate((yyvsp[(3) - (15)].qName), (yyvsp[(14) - (15)].expr), parseInfo, (yylsp[(1) - (15)]), templ);
+
+ /* Now, let's add it to all the relevant templates. */
+ for(int i = 0; i < (yyvsp[(10) - (15)].qNameVector).count(); ++i) /* For each mode. */
+ {
+ const QXmlName &modeName = (yyvsp[(10) - (15)].qNameVector).at(i);
+
+ if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all) && (yyvsp[(10) - (15)].qNameVector).count() > 1)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The keyword %1 cannot occur with any other mode name.")
+ .arg(formatKeyword(QLatin1String("#all"))),
+ ReportContext::XTSE0530,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ /* For each pattern the template use. */
+ const TemplateMode::Ptr mode(parseInfo->modeFor(modeName));
+ for(int t = 0; t < ourPatterns.count(); ++t)
+ mode->templatePatterns.append(ourPatterns.at(t));
+ }
+ }
+ break;
+
+ case 24:
+/* Line 1269 of yacc.c. */
+#line 1673 "querytransformparser.ypp"
+ {
+ (yyval.enums.Double) = std::numeric_limits<xsDouble>::quiet_NaN();
+ }
+ break;
+
+ case 25:
+/* Line 1269 of yacc.c. */
+#line 1678 "querytransformparser.ypp"
+ {
+ const AtomicValue::Ptr val(Decimal::fromLexical((yyvsp[(2) - (2)].sval)));
+ if(val->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The value of attribute %1 must be of type %2, which %3 isn't.")
+ .arg(formatKeyword(QLatin1String("priority")),
+ formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsDecimal),
+ formatData((yyvsp[(2) - (2)].sval))),
+ ReportContext::XTSE0530,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ (yyval.enums.Double) = val->as<Numeric>()->toDouble();
+ }
+ break;
+
+ case 26:
+/* Line 1269 of yacc.c. */
+#line 1694 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName();
+ }
+ break;
+
+ case 28:
+/* Line 1269 of yacc.c. */
+#line 1700 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (2)].qName);
+ }
+ break;
+
+ case 30:
+/* Line 1269 of yacc.c. */
+#line 1706 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 32:
+/* Line 1269 of yacc.c. */
+#line 1711 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 33:
+/* Line 1269 of yacc.c. */
+#line 1715 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 34:
+/* Line 1269 of yacc.c. */
+#line 1719 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 39:
+/* Line 1269 of yacc.c. */
+#line 1730 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(6) - (7)].enums.Bool))
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+
+ if((yyvsp[(3) - (7)].sval) == QLatin1String("xmlns"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to redeclare prefix %1.")
+ .arg(formatKeyword(QLatin1String("xmlns"))),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if ((yyvsp[(5) - (7)].sval) == CommonNamespaces::XML || (yyvsp[(3) - (7)].sval) == QLatin1String("xml"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The prefix %1 cannot be bound. By default, it is already bound "
+ "to the namespace %2.")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(CommonNamespaces::XML)),
+ ReportContext::XQST0070,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(parseInfo->declaredPrefixes.contains((yyvsp[(3) - (7)].sval)))
+ {
+ /* This includes the case where the user has bound a default prefix(such
+ * as 'local') and now tries to do it again. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 is already declared in the prolog.")
+ .arg(formatKeyword((yyvsp[(3) - (7)].sval))),
+ ReportContext::XQST0033, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->declaredPrefixes.append((yyvsp[(3) - (7)].sval));
+
+ if((yyvsp[(5) - (7)].sval).isEmpty())
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(StandardNamespaces::UndeclarePrefix,
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix((yyvsp[(3) - (7)].sval))));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(parseInfo->staticContext->namePool()->allocateBinding((yyvsp[(3) - (7)].sval), (yyvsp[(5) - (7)].sval)));
+ }
+ }
+ }
+ break;
+
+ case 40:
+/* Line 1269 of yacc.c. */
+#line 1776 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare boundary-space"),
+ ReportContext::XQST0068, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setBoundarySpacePolicy((yyvsp[(3) - (4)].enums.boundarySpacePolicy));
+ parseInfo->registerDeclaration(ParserContext::BoundarySpaceDecl);
+ }
+ }
+ break;
+
+ case 41:
+/* Line 1269 of yacc.c. */
+#line 1790 "querytransformparser.ypp"
+ {
+ (yyval.enums.boundarySpacePolicy) = StaticContext::BSPStrip;
+ }
+ break;
+
+ case 42:
+/* Line 1269 of yacc.c. */
+#line 1795 "querytransformparser.ypp"
+ {
+ (yyval.enums.boundarySpacePolicy) = StaticContext::BSPPreserve;
+ }
+ break;
+
+ case 45:
+/* Line 1269 of yacc.c. */
+#line 1804 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default element namespace"),
+ ReportContext::XQST0066, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(5) - (6)].sval)), StandardLocalNames::empty));
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultElementNamespace);
+ }
+ }
+ break;
+
+ case 46:
+/* Line 1269 of yacc.c. */
+#line 1819 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default function namespace"),
+ ReportContext::XQST0066, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setDefaultFunctionNamespace((yyvsp[(5) - (6)].sval));
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultFunctionNamespace);
+ }
+ }
+ break;
+
+ case 47:
+/* Line 1269 of yacc.c. */
+#line 1833 "querytransformparser.ypp"
+ {
+ if((yyvsp[(3) - (5)].qName).prefix() == StandardPrefixes::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an option must have a prefix. "
+ "There is no default namespace for options."),
+ ReportContext::XPST0081, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 48:
+/* Line 1269 of yacc.c. */
+#line 1843 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0065, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::OrderingModeDecl);
+ parseInfo->staticContext->setOrderingMode((yyvsp[(3) - (4)].enums.orderingMode));
+ }
+ }
+ break;
+
+ case 49:
+/* Line 1269 of yacc.c. */
+#line 1858 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingMode) = StaticContext::Ordered;
+ }
+ break;
+
+ case 50:
+/* Line 1269 of yacc.c. */
+#line 1862 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingMode) = StaticContext::Unordered;
+ }
+ break;
+
+ case 51:
+/* Line 1269 of yacc.c. */
+#line 1867 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default order"),
+ ReportContext::XQST0069, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::EmptyOrderDecl);
+ parseInfo->staticContext->setOrderingEmptySequence((yyvsp[(4) - (5)].enums.orderingEmptySequence));
+ }
+ }
+ break;
+
+ case 52:
+/* Line 1269 of yacc.c. */
+#line 1881 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = StaticContext::Least;
+ }
+ break;
+
+ case 53:
+/* Line 1269 of yacc.c. */
+#line 1885 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = StaticContext::Greatest;
+ }
+ break;
+
+ case 54:
+/* Line 1269 of yacc.c. */
+#line 1891 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare copy-namespaces"),
+ ReportContext::XQST0055, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::CopyNamespacesDecl);
+ }
+ }
+ break;
+
+ case 55:
+/* Line 1269 of yacc.c. */
+#line 1904 "querytransformparser.ypp"
+ {
+ parseInfo->preserveNamespacesMode = true;
+ }
+ break;
+
+ case 56:
+/* Line 1269 of yacc.c. */
+#line 1909 "querytransformparser.ypp"
+ {
+ parseInfo->preserveNamespacesMode = false;
+ }
+ break;
+
+ case 57:
+/* Line 1269 of yacc.c. */
+#line 1914 "querytransformparser.ypp"
+ {
+ parseInfo->inheritNamespacesMode = true;
+ }
+ break;
+
+ case 58:
+/* Line 1269 of yacc.c. */
+#line 1919 "querytransformparser.ypp"
+ {
+ parseInfo->inheritNamespacesMode = false;
+ }
+ break;
+
+ case 59:
+/* Line 1269 of yacc.c. */
+#line 1924 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default collation"),
+ ReportContext::XQST0038, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ const QUrl coll(resolveAndCheckCollation<ReportContext::XQST0038>((yyvsp[(4) - (5)].sval), parseInfo, (yyloc)));
+
+ parseInfo->registerDeclaration(ParserContext::DefaultCollationDecl);
+ parseInfo->staticContext->setDefaultCollation(coll);
+ }
+ }
+ break;
+
+ case 60:
+/* Line 1269 of yacc.c. */
+#line 1940 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, (yyloc), (yyvsp[(3) - (5)].enums.Bool));
+ if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare base-uri"),
+ ReportContext::XQST0032, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::BaseURIDecl);
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ QUrl toBeBase(AnyURI::toQUrl<ReportContext::XQST0046>((yyvsp[(4) - (5)].sval), parseInfo->staticContext, &ryy));
+ /* Now we're guaranteed that base is a valid lexical representation, but it can still be relative. */
+
+ if(toBeBase.isRelative())
+ toBeBase = parseInfo->staticContext->baseURI().resolved(toBeBase);
+
+ parseInfo->staticContext->setBaseURI(toBeBase);
+ }
+ }
+ break;
+
+ case 61:
+/* Line 1269 of yacc.c. */
+#line 1963 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Import feature is not supported, "
+ "and therefore %1 declarations cannot occur.")
+ .arg(formatKeyword("import schema")),
+ ReportContext::XQST0009, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 65:
+/* Line 1269 of yacc.c. */
+#line 1975 "querytransformparser.ypp"
+ {
+ if((yyvsp[(4) - (6)].sval).isEmpty())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The target namespace of a %1 cannot be empty.")
+ .arg(formatKeyword("module import")),
+ ReportContext::XQST0088, fromYYLTYPE((yyloc), parseInfo));
+
+ }
+ else
+ {
+ /* This is temporary until we have implemented it. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The module import feature is not supported"),
+ ReportContext::XQST0016, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 72:
+/* Line 1269 of yacc.c. */
+#line 2002 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(3) - (9)].enums.Bool));
+ if(variableByName((yyvsp[(5) - (9)].qName), parseInfo))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A variable with name %1 has already "
+ "been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical((yyvsp[(5) - (9)].qName)))),
+ parseInfo->isXSLT() ? ReportContext::XTSE0630 : ReportContext::XQST0049,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ if((yyvsp[(7) - (9)].expr)) /* We got a value assigned. */
+ {
+ const Expression::Ptr checked
+ (TypeChecker::applyFunctionConversion((yyvsp[(7) - (9)].expr), (yyvsp[(6) - (9)].sequenceType), parseInfo->staticContext,
+ (yyvsp[(3) - (9)].enums.Bool) ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ (yyvsp[(3) - (9)].enums.Bool) ? TypeChecker::Options(TypeChecker::CheckFocus | TypeChecker::AutomaticallyConvert) : TypeChecker::CheckFocus));
+
+ pushVariable((yyvsp[(5) - (9)].qName), (yyvsp[(6) - (9)].sequenceType), checked, VariableDeclaration::GlobalVariable, (yyloc), parseInfo);
+ parseInfo->declaredVariables.append(parseInfo->variables.last());
+ }
+ else /* We got an 'external' declaration. */
+ {
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable((yyvsp[(5) - (9)].qName), (yyvsp[(6) - (9)].sequenceType)));
+
+ if(varType)
+ {
+ /* We push the declaration such that we can see name clashes and so on, but we don't use it for tying
+ * any references to it. */
+ pushVariable((yyvsp[(5) - (9)].qName), varType, Expression::Ptr(), VariableDeclaration::ExternalVariable, (yyloc), parseInfo);
+ }
+ else if((yyvsp[(8) - (9)].expr))
+ {
+ /* Ok, the xsl:param got a default value, we make it
+ * available as a regular variable declaration. */
+ // TODO turn into checked
+ pushVariable((yyvsp[(5) - (9)].qName), (yyvsp[(6) - (9)].sequenceType), (yyvsp[(8) - (9)].expr), VariableDeclaration::GlobalVariable, (yyloc), parseInfo);
+ // TODO ensure that duplicates are trapped.
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No value is available for the external "
+ "variable with name %1.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (9)].qName))),
+ parseInfo->isXSLT() ? ReportContext::XTDE0050 : ReportContext::XPDY0002,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ }
+ }
+ break;
+
+ case 73:
+/* Line 1269 of yacc.c. */
+#line 2056 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 74:
+/* Line 1269 of yacc.c. */
+#line 2060 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 75:
+/* Line 1269 of yacc.c. */
+#line 2065 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 76:
+/* Line 1269 of yacc.c. */
+#line 2069 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 77:
+/* Line 1269 of yacc.c. */
+#line 2074 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0067, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::ConstructionDecl);
+ parseInfo->staticContext->setConstructionMode((yyvsp[(3) - (4)].enums.constructionMode));
+ }
+ }
+ break;
+
+ case 78:
+/* Line 1269 of yacc.c. */
+#line 2088 "querytransformparser.ypp"
+ {
+ (yyval.enums.constructionMode) = StaticContext::CMStrip;
+ }
+ break;
+
+ case 79:
+/* Line 1269 of yacc.c. */
+#line 2092 "querytransformparser.ypp"
+ {
+ (yyval.enums.constructionMode) = StaticContext::CMPreserve;
+ }
+ break;
+
+ case 80:
+/* Line 1269 of yacc.c. */
+#line 2097 "querytransformparser.ypp"
+ {
+ (yyval.enums.slot) = parseInfo->currentExpressionSlot() - (yyvsp[(6) - (7)].functionArguments).count();
+ }
+ break;
+
+ case 81:
+/* Line 1269 of yacc.c. */
+#line 2101 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(3) - (11)].enums.Bool))
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(3) - (11)].enums.Bool));
+
+ /* If FunctionBody is null, it is 'external', otherwise the value is the body. */
+ const QXmlName::NamespaceCode ns((yyvsp[(4) - (11)].qName).namespaceURI());
+
+ if(parseInfo->isXSLT() && !(yyvsp[(4) - (11)].qName).hasPrefix())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A stylesheet function must have a prefixed name."),
+ ReportContext::XTSE0740,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if((yyvsp[(10) - (11)].expr)) /* We got a function body. */
+ {
+ if(ns == StandardNamespaces::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace for a user defined function "
+ "cannot be empty (try the predefined "
+ "prefix %1 which exists for cases "
+ "like this)")
+ .arg(formatKeyword("local")),
+ ReportContext::XQST0060, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(XPathHelper::isReservedNamespace(ns))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace %1 is reserved; therefore "
+ "user defined functions may not use it. "
+ "Try the predefined prefix %2, which "
+ "exists for these cases.")
+ .arg(formatURI(parseInfo->staticContext->namePool(), ns), formatKeyword("local")),
+ parseInfo->isXSLT() ? ReportContext::XTSE0080 : ReportContext::XQST0045,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(parseInfo->moduleNamespace != StandardNamespaces::empty &&
+ ns != parseInfo->moduleNamespace)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace of a user defined "
+ "function in a library module must be "
+ "equivalent to the module namespace. "
+ "In other words, it should be %1 instead "
+ "of %2")
+ .arg(formatURI(parseInfo->staticContext->namePool(), parseInfo->moduleNamespace),
+ formatURI(parseInfo->staticContext->namePool(), ns)),
+ ReportContext::XQST0048, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ /* Apply function conversion such that the body matches the declared
+ * return type. */
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion((yyvsp[(10) - (11)].expr), (yyvsp[(9) - (11)].sequenceType),
+ parseInfo->staticContext,
+ ReportContext::XPTY0004,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert |
+ TypeChecker::CheckFocus |
+ TypeChecker::GeneratePromotion)));
+
+ const int argCount = (yyvsp[(6) - (11)].functionArguments).count();
+ const FunctionSignature::Ptr sign(new FunctionSignature((yyvsp[(4) - (11)].qName) /* name */,
+ argCount /* minArgs */,
+ argCount /* maxArgs */,
+ (yyvsp[(9) - (11)].sequenceType) /* returnType */));
+ sign->setArguments((yyvsp[(6) - (11)].functionArguments));
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it)
+ {
+ if(*(*it)->signature() == *sign)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A function already exists with "
+ "the signature %1.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), sign)),
+ parseInfo->isXSLT() ? ReportContext::XTSE0770 : ReportContext::XQST0034, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+
+ VariableDeclaration::List argDecls;
+
+ for(int i = 0; i < argCount; ++i)
+ argDecls.append(parseInfo->variables.at(i));
+
+ if((yyvsp[(8) - (11)].enums.slot) > -1)
+ {
+ /* We have allocated slots, so now push them out of scope. */
+ parseInfo->finalizePushedVariable(argCount);
+ }
+
+ parseInfo->userFunctions.append(UserFunction::Ptr(new UserFunction(sign, checked, (yyvsp[(8) - (11)].enums.slot), argDecls)));
+ }
+ }
+ else /* We got an 'external' declaration. */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No external functions are supported. "
+ "All supported functions can be used directly, "
+ "without first declaring them as external"),
+ ReportContext::XPST0017, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 82:
+/* Line 1269 of yacc.c. */
+#line 2205 "querytransformparser.ypp"
+ {
+ (yyval.functionArguments) = FunctionArgument::List();
+ }
+ break;
+
+ case 83:
+/* Line 1269 of yacc.c. */
+#line 2209 "querytransformparser.ypp"
+ {
+ FunctionArgument::List l;
+ l.append((yyvsp[(1) - (1)].functionArgument));
+ (yyval.functionArguments) = l;
+ }
+ break;
+
+ case 84:
+/* Line 1269 of yacc.c. */
+#line 2215 "querytransformparser.ypp"
+ {
+ FunctionArgument::List::const_iterator it((yyvsp[(1) - (3)].functionArguments).constBegin());
+ const FunctionArgument::List::const_iterator end((yyvsp[(1) - (3)].functionArguments).constEnd());
+
+ for(; it != end; ++it)
+ {
+ if((*it)->name() == (yyvsp[(3) - (3)].functionArgument)->name())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An argument with name %1 has already "
+ "been declared. Every argument name "
+ "must be unique.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (3)].functionArgument)->name())),
+ ReportContext::XQST0039, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+
+ (yyvsp[(1) - (3)].functionArguments).append((yyvsp[(3) - (3)].functionArgument));
+ (yyval.functionArguments) = (yyvsp[(1) - (3)].functionArguments);
+ }
+ break;
+
+ case 85:
+/* Line 1269 of yacc.c. */
+#line 2236 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType), Expression::Ptr(), VariableDeclaration::FunctionArgument, (yyloc), parseInfo);
+ (yyval.functionArgument) = FunctionArgument::Ptr(new FunctionArgument((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType)));
+ }
+ break;
+
+ case 86:
+/* Line 1269 of yacc.c. */
+#line 2242 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 88:
+/* Line 1269 of yacc.c. */
+#line 2248 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 91:
+/* Line 1269 of yacc.c. */
+#line 2264 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), CombineNodes::Union, (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 93:
+/* Line 1269 of yacc.c. */
+#line 2270 "querytransformparser.ypp"
+ {
+ /* We write this into a node test. The spec says, 5.5.3 The Meaning of a Pattern:
+ * "Similarly, / matches a document node, and only a document node,
+ * because the result of the expression root(.)//(/) returns the root
+ * node of the tree containing the context node if and only if it is a
+ * document node." */
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisSelf, BuiltinTypes::document), (yyloc), parseInfo);
+ }
+ break;
+
+ case 94:
+/* Line 1269 of yacc.c. */
+#line 2279 "querytransformparser.ypp"
+ {
+ /* /axis::node-test
+ * =>
+ * axis::node-test[parent::document-node()]
+ *
+ * In practice it looks like this. $2 is:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep parent::element(b)
+ * AxisStep parent::element(a)
+ *
+ * and we want this:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep self::element(b)
+ * TruthPredicate
+ * AxisStep parent::element(a)
+ * AxisStep parent::document()
+ *
+ * So we want to rewrite the predicate deepest down into a
+ * another TruthPredicate containing the AxisStep.
+ *
+ * The simplest case where $2 is only an axis step is special. When $2 is:
+ *
+ * AxisStep self::element(a)
+ *
+ * we want:
+ *
+ * TruthPredicate
+ * AxisStep self::element(a)
+ * AxisStep parent::document()
+ */
+
+ /* First, find the target. */
+ Expression::Ptr target((yyvsp[(2) - (2)].expr));
+
+ while(isPredicate(target->id()))
+ {
+ const Expression::Ptr candidate(target->operands().at(1));
+
+ if(isPredicate(candidate->id()))
+ target = candidate;
+ else
+ break; /* target is now the last predicate. */
+ }
+
+ if(target->is(Expression::IDAxisStep))
+ {
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(2) - (2)].expr), create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), (yyloc), parseInfo),
+ parseInfo->staticContext, fromYYLTYPE((yylsp[(1) - (2)]), parseInfo)), (yylsp[(1) - (2)]), parseInfo);
+ }
+ else
+ {
+ const Expression::List targetOperands(target->operands());
+ Expression::List newOps;
+ newOps.append(targetOperands.at(0));
+
+ newOps.append(create(GenericPredicate::create(targetOperands.at(1),
+ create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), (yyloc), parseInfo),
+ parseInfo->staticContext, fromYYLTYPE((yylsp[(1) - (2)]), parseInfo)), (yylsp[(1) - (2)]), parseInfo));
+
+ target->setOperands(newOps);
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ }
+ break;
+
+ case 95:
+/* Line 1269 of yacc.c. */
+#line 2349 "querytransformparser.ypp"
+ {
+ /* //axis::node-test
+ * =>
+ * axis::node-test[parent::node()]
+ *
+ * Spec says: "//para matches any para element that has a parent node."
+ */
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(2) - (2)].expr), create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), (yyloc), parseInfo),
+ parseInfo->staticContext, fromYYLTYPE((yylsp[(1) - (2)]), parseInfo)), (yylsp[(1) - (2)]), parseInfo);
+ }
+ break;
+
+ case 97:
+/* Line 1269 of yacc.c. */
+#line 2361 "querytransformparser.ypp"
+ {
+ createIdPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisParent, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 98:
+/* Line 1269 of yacc.c. */
+#line 2365 "querytransformparser.ypp"
+ {
+ createIdPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisAncestor, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 99:
+/* Line 1269 of yacc.c. */
+#line 2370 "querytransformparser.ypp"
+ {
+ const Expression::List ands((yyvsp[(1) - (1)].expr)->operands());
+ const FunctionSignature::Ptr signature((yyvsp[(1) - (1)].expr)->as<FunctionCall>()->signature());
+ const QXmlName name(signature->name());
+ const QXmlName key(StandardNamespaces::fn, StandardLocalNames::key);
+ const QXmlName id(StandardNamespaces::fn, StandardLocalNames::id);
+
+ if(name == id)
+ {
+ const Expression::ID id = ands.first()->id();
+ if(!isVariableReference(id) && id != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("When function %1 is used for matching inside a pattern, "
+ "the argument must be a variable reference or a string literal.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ else if(name == key)
+ {
+ if(ands.first()->id() != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a string literal, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ const Expression::ID id2 = ands.at(1)->id();
+ if(!isVariableReference(id2) &&
+ id2 != Expression::IDStringValue &&
+ id2 != Expression::IDIntegerValue &&
+ id2 != Expression::IDBooleanValue &&
+ id2 != Expression::IDFloat)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a literal or a variable reference, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(ands.count() == 3)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, function %1 cannot have a third argument.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ }
+ else
+ {
+ const FunctionSignature::Hash signs(parseInfo->staticContext->functionSignatures()->functionSignatures());
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, only function %1 "
+ "and %2, not %3, can be used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signs.value(id)),
+ formatFunction(parseInfo->staticContext->namePool(), signs.value(key)),
+ formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ (yyval.expr) = (yyvsp[(1) - (1)].expr);
+ }
+ break;
+
+ case 101:
+/* Line 1269 of yacc.c. */
+#line 2440 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisParent, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 102:
+/* Line 1269 of yacc.c. */
+#line 2444 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisAncestor, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 103:
+/* Line 1269 of yacc.c. */
+#line 2449 "querytransformparser.ypp"
+ {
+ const Expression::Ptr expr(findAxisStep((yyvsp[(1) - (1)].expr)));
+
+ const QXmlNodeModelIndex::Axis axis = expr->as<AxisStep>()->axis();
+ AxisStep *const axisStep = expr->as<AxisStep>();
+
+ /* Here we constrain the possible axes, and we rewrite the axes as according
+ * to 5.5.3 The Meaning of a Pattern.
+ *
+ * However, we also rewrite axis child and attribute to axis self. The
+ * reason for this is that if we don't, we will match the children of
+ * the context node, instead of the context node itself. The formal
+ * definition of a pattern, root(.)//EE is insensitive to context,
+ * while the way we implement pattern, "the other way of seeing it",
+ * e.g from right to left, are very much. */
+
+ if(axisStep->nodeTest() == BuiltinTypes::document
+ || axis == QXmlNodeModelIndex::AxisChild)
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ else if(axis == QXmlNodeModelIndex::AxisAttribute)
+ {
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ /* Consider that the user write attribute::node(). This is
+ * semantically equivalent to attribute::attribute(), but since we have changed
+ * the axis to axis self, we also need to change the node test, such that we
+ * have self::attribute(). */
+ if(*axisStep->nodeTest() == *BuiltinTypes::node)
+ axisStep->setNodeTest(BuiltinTypes::attribute);
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, axis %1 cannot be used, "
+ "only axis %2 or %3 can.")
+ .arg(formatKeyword(AxisStep::axisName(axis)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisChild)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisAttribute))),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ (yyval.expr) = (yyvsp[(1) - (1)].expr);
+ }
+ break;
+
+ case 105:
+/* Line 1269 of yacc.c. */
+#line 2494 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ExpressionSequence((yyvsp[(1) - (1)].expressionList)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 106:
+/* Line 1269 of yacc.c. */
+#line 2499 "querytransformparser.ypp"
+ {
+ Expression::List l;
+ l.append((yyvsp[(1) - (3)].expr));
+ l.append((yyvsp[(3) - (3)].expr));
+ (yyval.expressionList) = l;
+ }
+ break;
+
+ case 107:
+/* Line 1269 of yacc.c. */
+#line 2506 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (3)].expressionList).append((yyvsp[(3) - (3)].expr));
+ (yyval.expressionList) = (yyvsp[(1) - (3)].expressionList);
+ }
+ break;
+
+ case 113:
+/* Line 1269 of yacc.c. */
+#line 2517 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(3) - (4)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 114:
+/* Line 1269 of yacc.c. */
+#line 2522 "querytransformparser.ypp"
+ {
+ QVector<QXmlName> result;
+ result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
+ (yyval.qNameVector) = result;
+ }
+ break;
+
+ case 115:
+/* Line 1269 of yacc.c. */
+#line 2528 "querytransformparser.ypp"
+ {
+ (yyval.qNameVector) = (yyvsp[(2) - (2)].qNameVector);
+ }
+ break;
+
+ case 116:
+/* Line 1269 of yacc.c. */
+#line 2533 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ }
+ break;
+
+ case 117:
+/* Line 1269 of yacc.c. */
+#line 2537 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (2)].qName);
+ }
+ break;
+
+ case 118:
+/* Line 1269 of yacc.c. */
+#line 2542 "querytransformparser.ypp"
+ {
+ QVector<QXmlName> result;
+ result.append((yyvsp[(1) - (1)].qName));
+ (yyval.qNameVector) = result;
+ }
+ break;
+
+ case 119:
+/* Line 1269 of yacc.c. */
+#line 2548 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (3)].qNameVector).append((yyvsp[(3) - (3)].qName));
+ (yyval.qNameVector) = (yyvsp[(1) - (3)].qNameVector);
+ }
+ break;
+
+ case 120:
+/* Line 1269 of yacc.c. */
+#line 2554 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(1) - (1)].qName);
+ }
+ break;
+
+ case 121:
+/* Line 1269 of yacc.c. */
+#line 2558 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (1)].sval) == QLatin1String("#current"))
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current);
+ else if((yyvsp[(1) - (1)].sval) == QLatin1String("#default"))
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ else if((yyvsp[(1) - (1)].sval) == QLatin1String("#all"))
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all);
+ else
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ if(!QXmlUtils::isNCName((yyvsp[(1) - (1)].sval)))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid template mode name.")
+ .arg(formatKeyword((yyvsp[(1) - (1)].sval))),
+ ReportContext::XTSE0550,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval));
+ }
+ }
+ break;
+
+ case 124:
+/* Line 1269 of yacc.c. */
+#line 2587 "querytransformparser.ypp"
+ {
+ /* We're pushing the range variable here, not the positional. */
+ (yyval.expr) = pushVariable((yyvsp[(3) - (7)].qName), quantificationType((yyvsp[(4) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 125:
+/* Line 1269 of yacc.c. */
+#line 2591 "querytransformparser.ypp"
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ (yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();
+ }
+ break;
+
+ case 126:
+/* Line 1269 of yacc.c. */
+#line 2598 "querytransformparser.ypp"
+ {
+ Q_ASSERT((yyvsp[(7) - (10)].expr));
+ Q_ASSERT((yyvsp[(10) - (10)].expr));
+
+ /* We want the next last pushed variable, since we push the range variable after the
+ * positional variable. */
+ if((yyvsp[(5) - (10)].enums.slot) != -1 && parseInfo->variables.at(parseInfo->variables.count() -2)->name == (yyvsp[(3) - (10)].qName))
+ {
+ /* Ok, a positional variable is used since its slot is not -1, and its name is equal
+ * to our range variable. This is an error. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of a variable bound in a for-expression must be different "
+ "from the positional variable. Hence, the two variables named %1 collide.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (10)].qName))),
+ ReportContext::XQST0089,
+ fromYYLTYPE((yyloc), parseInfo));
+
+ }
+
+ const Expression::Ptr retBody(create(new ForClause((yyvsp[(9) - (10)].enums.slot), (yyvsp[(8) - (10)].expr), (yyvsp[(10) - (10)].expr), (yyvsp[(5) - (10)].enums.slot)), (yyloc), parseInfo));
+ ReturnOrderBy *const rob = locateReturnClause((yyvsp[(10) - (10)].expr));
+
+ if(rob)
+ (yyval.expr) = create(new OrderBy(rob->stability(), rob->orderSpecs(), retBody, rob), (yyloc), parseInfo);
+ else
+ (yyval.expr) = retBody;
+
+ parseInfo->finalizePushedVariable();
+
+ if((yyvsp[(5) - (10)].enums.slot) != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 127:
+/* Line 1269 of yacc.c. */
+#line 2632 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (7)].qName), quantificationType((yyvsp[(4) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 128:
+/* Line 1269 of yacc.c. */
+#line 2635 "querytransformparser.ypp"
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ (yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();
+ }
+ break;
+
+ case 129:
+/* Line 1269 of yacc.c. */
+#line 2642 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ForClause((yyvsp[(9) - (10)].enums.slot), (yyvsp[(7) - (10)].expr), (yyvsp[(10) - (10)].expr), (yyvsp[(5) - (10)].enums.slot)), (yyloc), parseInfo);
+
+ parseInfo->finalizePushedVariable();
+
+ if((yyvsp[(5) - (10)].enums.slot) != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 133:
+/* Line 1269 of yacc.c. */
+#line 2656 "querytransformparser.ypp"
+ {
+ (yyval.enums.slot) = -1;
+ }
+ break;
+
+ case 134:
+/* Line 1269 of yacc.c. */
+#line 2661 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (3)].qName), CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(),
+ VariableDeclaration::PositionalVariable, (yyloc), parseInfo);
+ (yyval.enums.slot) = parseInfo->currentPositionSlot();
+ }
+ break;
+
+ case 135:
+/* Line 1269 of yacc.c. */
+#line 2668 "querytransformparser.ypp"
+ {
+ (yyval.expr) = pushVariable((yyvsp[(4) - (7)].qName), quantificationType((yyvsp[(5) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::ExpressionVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 136:
+/* Line 1269 of yacc.c. */
+#line 2672 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (9)].enums.Bool));
+
+ Q_ASSERT(parseInfo->variables.top()->name == (yyvsp[(4) - (9)].qName));
+ (yyval.expr) = create(new LetClause((yyvsp[(8) - (9)].expr), (yyvsp[(9) - (9)].expr), parseInfo->variables.top()), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 137:
+/* Line 1269 of yacc.c. */
+#line 2681 "querytransformparser.ypp"
+ { (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr), VariableDeclaration::ExpressionVariable, (yyloc), parseInfo);}
+ break;
+
+ case 138:
+/* Line 1269 of yacc.c. */
+#line 2683 "querytransformparser.ypp"
+ {
+ Q_ASSERT(parseInfo->variables.top()->name == (yyvsp[(3) - (8)].qName));
+ (yyval.expr) = create(new LetClause((yyvsp[(7) - (8)].expr), (yyvsp[(8) - (8)].expr), parseInfo->variables.top()), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 142:
+/* Line 1269 of yacc.c. */
+#line 2694 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (3)].orderSpecs).isEmpty())
+ (yyval.expr) = (yyvsp[(3) - (3)].expr);
+ else
+ (yyval.expr) = createReturnOrderBy((yyvsp[(1) - (3)].orderSpecs), (yyvsp[(3) - (3)].expr), parseInfo->orderStability.pop(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 143:
+/* Line 1269 of yacc.c. */
+#line 2702 "querytransformparser.ypp"
+ {
+ if((yyvsp[(3) - (5)].orderSpecs).isEmpty())
+ (yyval.expr) = create(new IfThenClause((yyvsp[(2) - (5)].expr), (yyvsp[(5) - (5)].expr), create(new EmptySequence, (yyloc), parseInfo)), (yyloc), parseInfo);
+ else
+ (yyval.expr) = create(new IfThenClause((yyvsp[(2) - (5)].expr), createReturnOrderBy((yyvsp[(3) - (5)].orderSpecs), (yyvsp[(5) - (5)].expr), parseInfo->orderStability.pop(), (yyloc), parseInfo),
+ create(new EmptySequence, (yyloc), parseInfo)),
+ (yyloc), parseInfo);
+ }
+ break;
+
+ case 144:
+/* Line 1269 of yacc.c. */
+#line 2712 "querytransformparser.ypp"
+ {
+ (yyval.orderSpecs) = OrderSpecTransfer::List();
+ }
+ break;
+
+ case 146:
+/* Line 1269 of yacc.c. */
+#line 2718 "querytransformparser.ypp"
+ {
+ (yyval.orderSpecs) = (yyvsp[(2) - (2)].orderSpecs);
+ }
+ break;
+
+ case 147:
+/* Line 1269 of yacc.c. */
+#line 2723 "querytransformparser.ypp"
+ {
+ OrderSpecTransfer::List list;
+ list += (yyvsp[(1) - (3)].orderSpecs);
+ list.append((yyvsp[(3) - (3)].orderSpec));
+ (yyval.orderSpecs) = list;
+ }
+ break;
+
+ case 148:
+/* Line 1269 of yacc.c. */
+#line 2730 "querytransformparser.ypp"
+ {
+ OrderSpecTransfer::List list;
+ list.append((yyvsp[(1) - (1)].orderSpec));
+ (yyval.orderSpecs) = list;
+ }
+ break;
+
+ case 149:
+/* Line 1269 of yacc.c. */
+#line 2737 "querytransformparser.ypp"
+ {
+ (yyval.orderSpec) = OrderSpecTransfer((yyvsp[(1) - (4)].expr), OrderBy::OrderSpec((yyvsp[(2) - (4)].enums.sortDirection), (yyvsp[(3) - (4)].enums.orderingEmptySequence)));
+ }
+ break;
+
+ case 150:
+/* Line 1269 of yacc.c. */
+#line 2742 "querytransformparser.ypp"
+ {
+ /* Where does the specification state the default value is ascending?
+ *
+ * It is implicit, in the first enumerated list in 3.8.3 Order By and Return Clauses:
+ *
+ * "If T1 and T2 are two tuples in the tuple stream, and V1 and V2 are the first pair
+ * of values encountered when evaluating their orderspecs from left to right for
+ * which one value is greater-than the other (as defined above), then:
+ *
+ * 1. If V1 is greater-than V2: If the orderspec specifies descending,
+ * then T1 precedes T2 in the tuple stream; otherwise, T2 precedes T1 in the tuple stream.
+ * 2. If V2 is greater-than V1: If the orderspec specifies descending,
+ * then T2 precedes T1 in the tuple stream; otherwise, T1 precedes T2 in the tuple stream."
+ *
+ * which means that if you don't specify anything, or you
+ * specify ascending, you get the same result.
+ */
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Ascending;
+ }
+ break;
+
+ case 151:
+/* Line 1269 of yacc.c. */
+#line 2763 "querytransformparser.ypp"
+ {
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Ascending;
+ }
+ break;
+
+ case 152:
+/* Line 1269 of yacc.c. */
+#line 2768 "querytransformparser.ypp"
+ {
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Descending;
+ }
+ break;
+
+ case 153:
+/* Line 1269 of yacc.c. */
+#line 2773 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = parseInfo->staticContext->orderingEmptySequence();
+ }
+ break;
+
+ case 156:
+/* Line 1269 of yacc.c. */
+#line 2780 "querytransformparser.ypp"
+ {
+ if(parseInfo->isXSLT())
+ resolveAndCheckCollation<ReportContext::XTDE1035>((yyvsp[(2) - (2)].sval), parseInfo, (yyloc));
+ else
+ resolveAndCheckCollation<ReportContext::XQST0076>((yyvsp[(2) - (2)].sval), parseInfo, (yyloc));
+ }
+ break;
+
+ case 157:
+/* Line 1269 of yacc.c. */
+#line 2787 "querytransformparser.ypp"
+ {
+ /* We do nothing. We don't use collations, and we have this non-terminal
+ * in order to accept expressions. */
+ }
+ break;
+
+ case 158:
+/* Line 1269 of yacc.c. */
+#line 2793 "querytransformparser.ypp"
+ {
+ parseInfo->orderStability.push(OrderBy::StableOrder);
+ }
+ break;
+
+ case 159:
+/* Line 1269 of yacc.c. */
+#line 2797 "querytransformparser.ypp"
+ {
+ parseInfo->orderStability.push(OrderBy::UnstableOrder);
+ }
+ break;
+
+ case 162:
+/* Line 1269 of yacc.c. */
+#line 2805 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 163:
+/* Line 1269 of yacc.c. */
+#line 2809 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 164:
+/* Line 1269 of yacc.c. */
+#line 2811 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Some, (yyvsp[(6) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 165:
+/* Line 1269 of yacc.c. */
+#line 2819 "querytransformparser.ypp"
+ {
+ (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 166:
+/* Line 1269 of yacc.c. */
+#line 2823 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 167:
+/* Line 1269 of yacc.c. */
+#line 2825 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Some, (yyvsp[(7) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 169:
+/* Line 1269 of yacc.c. */
+#line 2834 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 170:
+/* Line 1269 of yacc.c. */
+#line 2838 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 171:
+/* Line 1269 of yacc.c. */
+#line 2840 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Every, (yyvsp[(6) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 172:
+/* Line 1269 of yacc.c. */
+#line 2848 "querytransformparser.ypp"
+ {
+ (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 173:
+/* Line 1269 of yacc.c. */
+#line 2852 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 174:
+/* Line 1269 of yacc.c. */
+#line 2854 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Every, (yyvsp[(7) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 176:
+/* Line 1269 of yacc.c. */
+#line 2863 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 177:
+/* Line 1269 of yacc.c. */
+#line 2890 "querytransformparser.ypp"
+ {
+ parseInfo->typeswitchSource.push((yyvsp[(3) - (4)].expr));
+ }
+ break;
+
+ case 178:
+/* Line 1269 of yacc.c. */
+#line 2894 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ parseInfo->typeswitchSource.pop();
+ (yyval.expr) = (yyvsp[(6) - (6)].expr);
+ }
+ break;
+
+ case 179:
+/* Line 1269 of yacc.c. */
+#line 2901 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(2) - (3)].qName).isNull())
+ {
+ pushVariable((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType), parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, (yyloc), parseInfo, false);
+ }
+ }
+ break;
+
+ case 180:
+/* Line 1269 of yacc.c. */
+#line 2909 "querytransformparser.ypp"
+ {
+ /* The variable shouldn't be in-scope for other case branches. */
+ if(!(yyvsp[(2) - (6)].qName).isNull())
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 181:
+/* Line 1269 of yacc.c. */
+#line 2915 "querytransformparser.ypp"
+ {
+ const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), (yyvsp[(3) - (8)].sequenceType)), (yyloc), parseInfo));
+ (yyval.expr) = create(new IfThenClause(instanceOf, (yyvsp[(6) - (8)].expr), (yyvsp[(8) - (8)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 184:
+/* Line 1269 of yacc.c. */
+#line 2924 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName();
+ }
+ break;
+
+ case 185:
+/* Line 1269 of yacc.c. */
+#line 2929 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (3)].qName);
+ }
+ break;
+
+ case 186:
+/* Line 1269 of yacc.c. */
+#line 2934 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(3) - (3)].expr);
+ }
+ break;
+
+ case 187:
+/* Line 1269 of yacc.c. */
+#line 2938 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(3) - (3)].qName).isNull())
+ {
+ pushVariable((yyvsp[(3) - (3)].qName), parseInfo->typeswitchSource.top()->staticType(),
+ parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, (yyloc), parseInfo, false);
+ }
+ }
+ break;
+
+ case 188:
+/* Line 1269 of yacc.c. */
+#line 2947 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(3) - (6)].qName).isNull())
+ parseInfo->finalizePushedVariable();
+ (yyval.expr) = (yyvsp[(6) - (6)].expr);
+ }
+ break;
+
+ case 189:
+/* Line 1269 of yacc.c. */
+#line 2954 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new IfThenClause((yyvsp[(3) - (8)].expr), (yyvsp[(6) - (8)].expr), (yyvsp[(8) - (8)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 191:
+/* Line 1269 of yacc.c. */
+#line 2961 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new OrExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 193:
+/* Line 1269 of yacc.c. */
+#line 2968 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new AndExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 199:
+/* Line 1269 of yacc.c. */
+#line 2980 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new RangeExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 201:
+/* Line 1269 of yacc.c. */
+#line 2987 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new ArithmeticExpression((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.mathOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 202:
+/* Line 1269 of yacc.c. */
+#line 2992 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Add;}
+ break;
+
+ case 203:
+/* Line 1269 of yacc.c. */
+#line 2993 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Substract;}
+ break;
+
+ case 205:
+/* Line 1269 of yacc.c. */
+#line 2997 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new ArithmeticExpression((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.mathOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 206:
+/* Line 1269 of yacc.c. */
+#line 3002 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Multiply;}
+ break;
+
+ case 207:
+/* Line 1269 of yacc.c. */
+#line 3003 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Div;}
+ break;
+
+ case 208:
+/* Line 1269 of yacc.c. */
+#line 3004 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::IDiv;}
+ break;
+
+ case 209:
+/* Line 1269 of yacc.c. */
+#line 3005 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Mod;}
+ break;
+
+ case 211:
+/* Line 1269 of yacc.c. */
+#line 3009 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10
+ | QXmlQuery::XPath20
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector),
+ parseInfo, (yyloc));
+ (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), CombineNodes::Union, (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 213:
+/* Line 1269 of yacc.c. */
+#line 3020 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.combinedNodeOp), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 216:
+/* Line 1269 of yacc.c. */
+#line 3029 "querytransformparser.ypp"
+ {
+ (yyval.enums.combinedNodeOp) = CombineNodes::Intersect;
+ }
+ break;
+
+ case 217:
+/* Line 1269 of yacc.c. */
+#line 3033 "querytransformparser.ypp"
+ {
+ (yyval.enums.combinedNodeOp) = CombineNodes::Except;
+ }
+ break;
+
+ case 219:
+/* Line 1269 of yacc.c. */
+#line 3039 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new InstanceOf((yyvsp[(1) - (4)].expr),
+ SequenceType::Ptr((yyvsp[(4) - (4)].sequenceType))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 221:
+/* Line 1269 of yacc.c. */
+#line 3047 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new TreatAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 223:
+/* Line 1269 of yacc.c. */
+#line 3054 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new CastableAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 225:
+/* Line 1269 of yacc.c. */
+#line 3061 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new CastAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 227:
+/* Line 1269 of yacc.c. */
+#line 3068 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new UnaryExpression((yyvsp[(1) - (2)].enums.mathOperator), (yyvsp[(2) - (2)].expr), parseInfo->staticContext), (yyloc), parseInfo);
+ }
+ break;
+
+ case 228:
+/* Line 1269 of yacc.c. */
+#line 3074 "querytransformparser.ypp"
+ {
+ (yyval.enums.mathOperator) = AtomicMathematician::Add;
+ }
+ break;
+
+ case 229:
+/* Line 1269 of yacc.c. */
+#line 3078 "querytransformparser.ypp"
+ {
+ (yyval.enums.mathOperator) = AtomicMathematician::Substract;
+ }
+ break;
+
+ case 233:
+/* Line 1269 of yacc.c. */
+#line 3087 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new GeneralComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.valueOperator), (yyvsp[(3) - (3)].expr), parseInfo->isBackwardsCompat.top()), (yyloc), parseInfo);
+ }
+ break;
+
+ case 234:
+/* Line 1269 of yacc.c. */
+#line 3092 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;}
+ break;
+
+ case 235:
+/* Line 1269 of yacc.c. */
+#line 3093 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;}
+ break;
+
+ case 236:
+/* Line 1269 of yacc.c. */
+#line 3094 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;}
+ break;
+
+ case 237:
+/* Line 1269 of yacc.c. */
+#line 3095 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;}
+ break;
+
+ case 238:
+/* Line 1269 of yacc.c. */
+#line 3096 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;}
+ break;
+
+ case 239:
+/* Line 1269 of yacc.c. */
+#line 3097 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;}
+ break;
+
+ case 240:
+/* Line 1269 of yacc.c. */
+#line 3100 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ValueComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.valueOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 241:
+/* Line 1269 of yacc.c. */
+#line 3104 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;}
+ break;
+
+ case 242:
+/* Line 1269 of yacc.c. */
+#line 3105 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;}
+ break;
+
+ case 243:
+/* Line 1269 of yacc.c. */
+#line 3106 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;}
+ break;
+
+ case 244:
+/* Line 1269 of yacc.c. */
+#line 3107 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;}
+ break;
+
+ case 245:
+/* Line 1269 of yacc.c. */
+#line 3108 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;}
+ break;
+
+ case 246:
+/* Line 1269 of yacc.c. */
+#line 3109 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;}
+ break;
+
+ case 247:
+/* Line 1269 of yacc.c. */
+#line 3112 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new NodeComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.nodeOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 248:
+/* Line 1269 of yacc.c. */
+#line 3116 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Is;}
+ break;
+
+ case 249:
+/* Line 1269 of yacc.c. */
+#line 3117 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Precedes;}
+ break;
+
+ case 250:
+/* Line 1269 of yacc.c. */
+#line 3118 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Follows;}
+ break;
+
+ case 251:
+/* Line 1269 of yacc.c. */
+#line 3121 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. "
+ "Hence, %1-expressions may not be used.")
+ .arg(formatKeyword("validate")),
+ ReportContext::XQST0075, fromYYLTYPE((yyloc), parseInfo));
+ /*
+ $$ = Validate::create($2, $1, parseInfo->staticContext);
+ */
+ }
+ break;
+
+ case 252:
+/* Line 1269 of yacc.c. */
+#line 3134 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Strict;}
+ break;
+
+ case 253:
+/* Line 1269 of yacc.c. */
+#line 3135 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Strict;}
+ break;
+
+ case 254:
+/* Line 1269 of yacc.c. */
+#line 3136 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Lax;}
+ break;
+
+ case 255:
+/* Line 1269 of yacc.c. */
+#line 3139 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ /* We don't support any pragmas, so we only do the
+ * necessary validation and use the fallback expression. */
+
+ if((yyvsp[(2) - (2)].expr))
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("None of the pragma expressions are supported. "
+ "Therefore, a fallback expression "
+ "must be present"),
+ ReportContext::XQST0079, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 256:
+/* Line 1269 of yacc.c. */
+#line 3156 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 257:
+/* Line 1269 of yacc.c. */
+#line 3160 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 260:
+/* Line 1269 of yacc.c. */
+#line 3168 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 263:
+/* Line 1269 of yacc.c. */
+#line 3176 "querytransformparser.ypp"
+ {
+ /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */
+ (yyval.expr) = create(new Path(createRootExpression(parseInfo, (yyloc)), (yyvsp[(2) - (2)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 264:
+/* Line 1269 of yacc.c. */
+#line 3182 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createSlashSlashPath(createRootExpression(parseInfo, (yyloc)), (yyvsp[(2) - (2)].expr), (yyloc), parseInfo);
+ }
+ break;
+
+ case 265:
+/* Line 1269 of yacc.c. */
+#line 3186 "querytransformparser.ypp"
+ {
+ /* This is "/". That is, fn:root(self::node()) treat as document-node(). */
+ (yyval.expr) = createRootExpression(parseInfo, (yyloc));
+ }
+ break;
+
+ case 268:
+/* Line 1269 of yacc.c. */
+#line 3196 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Path((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), (yyvsp[(2) - (3)].enums.pathKind)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 269:
+/* Line 1269 of yacc.c. */
+#line 3200 "querytransformparser.ypp"
+ {
+ const Expression::Ptr orderBy(createReturnOrderBy((yyvsp[(4) - (7)].orderSpecs), (yyvsp[(6) - (7)].expr), parseInfo->orderStability.pop(), (yyloc), parseInfo));
+
+ ReturnOrderBy *const rob = orderBy->as<ReturnOrderBy>();
+ const Expression::Ptr path(create(new Path((yyvsp[(1) - (7)].expr), orderBy, (yyvsp[(2) - (7)].enums.pathKind)), (yyloc), parseInfo));
+
+ (yyval.expr) = create(new OrderBy(rob->stability(), rob->orderSpecs(), path, rob), (yyloc), parseInfo);
+ }
+ break;
+
+ case 270:
+/* Line 1269 of yacc.c. */
+#line 3209 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createSlashSlashPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), (yyloc), parseInfo);
+ }
+ break;
+
+ case 271:
+/* Line 1269 of yacc.c. */
+#line 3214 "querytransformparser.ypp"
+ {
+ (yyval.expr) = NodeSortExpression::wrapAround((yyvsp[(1) - (1)].expr), parseInfo->staticContext);
+ }
+ break;
+
+ case 273:
+/* Line 1269 of yacc.c. */
+#line 3219 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CurrentItemStore((yyvsp[(2) - (2)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 274:
+/* Line 1269 of yacc.c. */
+#line 3223 "querytransformparser.ypp"
+ {
+ const xsDouble version = (yyvsp[(1) - (1)].sval).toDouble();
+
+ parseInfo->isBackwardsCompat.push(version != 2);
+
+ (yyval.enums.Double) = version;
+ }
+ break;
+
+ case 275:
+/* Line 1269 of yacc.c. */
+#line 3231 "querytransformparser.ypp"
+ {
+ if((yyvsp[(2) - (3)].enums.Double) < 2)
+ (yyval.expr) = createCompatStore((yyvsp[(3) - (3)].expr), (yyloc), parseInfo);
+ else
+ (yyval.expr) = (yyvsp[(3) - (3)].expr);
+ }
+ break;
+
+ case 276:
+/* Line 1269 of yacc.c. */
+#line 3238 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XSLT20, parseInfo, (yyloc));
+ Q_ASSERT(!(yyvsp[(2) - (5)].sval).isEmpty());
+ (yyval.expr) = create(new StaticBaseURIStore((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].expr)), (yyloc), parseInfo);
+}
+ break;
+
+ case 277:
+/* Line 1269 of yacc.c. */
+#line 3245 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, (yyloc));
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(5) - (6)].sval)),
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix((yyvsp[(3) - (6)].sval))));
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ }
+ break;
+
+ case 278:
+/* Line 1269 of yacc.c. */
+#line 3256 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ (yyval.expr) = (yyvsp[(8) - (9)].expr);
+ }
+ break;
+
+ case 279:
+/* Line 1269 of yacc.c. */
+#line 3261 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CallTemplate((yyvsp[(2) - (5)].qName), parseInfo->templateWithParams), (yyloc), parseInfo);
+ parseInfo->templateWithParametersHandled();
+ parseInfo->templateCalls.append((yyval.expr));
+ }
+ break;
+
+ case 280:
+/* Line 1269 of yacc.c. */
+#line 3268 "querytransformparser.ypp"
+ {
+ parseInfo->startParsingWithParam();
+ }
+ break;
+
+ case 281:
+/* Line 1269 of yacc.c. */
+#line 3272 "querytransformparser.ypp"
+ {
+ parseInfo->endParsingWithParam();
+ }
+ break;
+
+ case 282:
+/* Line 1269 of yacc.c. */
+#line 3277 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 283:
+/* Line 1269 of yacc.c. */
+#line 3280 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 284:
+/* Line 1269 of yacc.c. */
+#line 3283 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 285:
+/* Line 1269 of yacc.c. */
+#line 3287 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 286:
+/* Line 1269 of yacc.c. */
+#line 3290 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 287:
+/* Line 1269 of yacc.c. */
+#line 3294 "querytransformparser.ypp"
+ {
+ /* Note, this grammar rule is invoked for @c xsl:param @em and @c
+ * xsl:with-param. */
+ const bool isParsingWithParam = parseInfo->isParsingWithParam();
+
+ /**
+ * @c xsl:param doesn't make life easy:
+ *
+ * If it only has @c name, it's default value is an empty
+ * string(hence has type @c xs:string), but the value that
+ * (maybe) is supplied can be anything, typically a node.
+ *
+ * Therefore, for that very common case we can't rely on
+ * the Expression's type, but have to force it to item()*.
+ *
+ * So if we're supplied the type item()*, we pass a null
+ * SequenceType. TemplateParameterReference recognizes this
+ * and has item()* as its static type, regardless of if the
+ * expression has a more specific type.
+ */
+ SequenceType::Ptr type;
+
+ if(!(yyvsp[(4) - (5)].sequenceType)->is(CommonSequenceTypes::ZeroOrMoreItems))
+ type = (yyvsp[(4) - (5)].sequenceType);
+
+ Expression::Ptr expr;
+
+ /* The default value is an empty sequence. */
+ if(!(yyvsp[(5) - (5)].expr) && ((type && (yyvsp[(4) - (5)].sequenceType)->cardinality().allowsEmpty())
+ || isParsingWithParam))
+ expr = create(new EmptySequence, (yyloc), parseInfo);
+ else
+ expr = (yyvsp[(5) - (5)].expr);
+
+ /* We ensure we have some type, so CallTemplate, Template and friends
+ * are happy. */
+ if(!isParsingWithParam && !type)
+ type = CommonSequenceTypes::ZeroOrMoreItems;
+
+ if((yyvsp[(1) - (5)].enums.Bool))
+ /* TODO, handle tunnel parameters. */;
+ else
+ {
+ if((!isParsingWithParam && VariableDeclaration::contains(parseInfo->templateParameters, (yyvsp[(3) - (5)].qName))) ||
+ (isParsingWithParam && parseInfo->templateWithParams.contains((yyvsp[(3) - (5)].qName))))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Each name of a template parameter must be unique; %1 is duplicated.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (5)].qName))),
+ isParsingWithParam ? ReportContext::XTSE0670 : ReportContext::XTSE0580, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ if(isParsingWithParam)
+ parseInfo->templateWithParams[(yyvsp[(3) - (5)].qName)] = WithParam::Ptr(new WithParam((yyvsp[(3) - (5)].qName), (yyvsp[(4) - (5)].sequenceType), expr));
+ else
+ {
+ Q_ASSERT(type);
+ pushVariable((yyvsp[(3) - (5)].qName), type, expr, VariableDeclaration::TemplateParameter, (yyloc), parseInfo);
+ parseInfo->templateParameters.append(parseInfo->variables.top());
+ }
+ }
+ }
+ }
+ break;
+
+ case 288:
+/* Line 1269 of yacc.c. */
+#line 3359 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = false;
+ }
+ break;
+
+ case 289:
+/* Line 1269 of yacc.c. */
+#line 3363 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = true;
+ }
+ break;
+
+ case 290:
+/* Line 1269 of yacc.c. */
+#line 3368 "querytransformparser.ypp"
+ {
+ (yyval.expr) = Expression::Ptr();
+ }
+ break;
+
+ case 291:
+/* Line 1269 of yacc.c. */
+#line 3372 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 292:
+/* Line 1269 of yacc.c. */
+#line 3381 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::RegularPath;
+ }
+ break;
+
+ case 293:
+/* Line 1269 of yacc.c. */
+#line 3385 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::XSLTForEach;
+ }
+ break;
+
+ case 294:
+/* Line 1269 of yacc.c. */
+#line 3389 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::ForApplyTemplate;
+ }
+ break;
+
+ case 296:
+/* Line 1269 of yacc.c. */
+#line 3395 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr), parseInfo->staticContext, fromYYLTYPE((yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 299:
+/* Line 1269 of yacc.c. */
+#line 3403 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (1)].enums.axis) == QXmlNodeModelIndex::AxisAttribute)
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 300:
+/* Line 1269 of yacc.c. */
+#line 3408 "querytransformparser.ypp"
+ {
+ if((yyvsp[(3) - (3)].itemType))
+ {
+ /* A node test was explicitly specified. The un-abbreviated syntax was used. */
+ (yyval.expr) = create(new AxisStep((yyvsp[(1) - (3)].enums.axis), (yyvsp[(3) - (3)].itemType)), (yyloc), parseInfo);
+ }
+ else
+ {
+ /* Quote from 3.2.1.1 Axes
+ *
+ * [Definition: Every axis has a principal node kind. If an axis
+ * can contain elements, then the principal node kind is element;
+ * otherwise, it is the kind of nodes that the axis can contain.] Thus:
+ * - For the attribute axis, the principal node kind is attribute.
+ * - For all other axes, the principal node kind is element. */
+
+ if((yyvsp[(1) - (3)].enums.axis) == QXmlNodeModelIndex::AxisAttribute)
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, BuiltinTypes::attribute), (yyloc), parseInfo);
+ else
+ (yyval.expr) = create(new AxisStep((yyvsp[(1) - (3)].enums.axis), BuiltinTypes::element), (yyloc), parseInfo);
+ }
+
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 304:
+/* Line 1269 of yacc.c. */
+#line 3438 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (2)].enums.axis) == QXmlNodeModelIndex::AxisNamespace)
+ {
+ /* We don't raise XPST0010 here because the namespace axis isn't an optional
+ * axis. It simply is not part of the XQuery grammar. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The %1-axis is unsupported in XQuery")
+ .arg(formatKeyword("namespace")),
+ ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ (yyval.enums.axis) = (yyvsp[(1) - (2)].enums.axis);
+
+ switch((yyvsp[(1) - (2)].enums.axis))
+ {
+ case QXmlNodeModelIndex::AxisAttribute:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XSLT20),
+ parseInfo, (yyloc));
+ break;
+ }
+ case QXmlNodeModelIndex::AxisChild:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector
+ | QXmlQuery::XSLT20),
+ parseInfo, (yyloc));
+ break;
+ }
+ default:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XSLT20),
+ parseInfo, (yyloc));
+ }
+ }
+ }
+ break;
+
+ case 305:
+/* Line 1269 of yacc.c. */
+#line 3481 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestorOrSelf ;}
+ break;
+
+ case 306:
+/* Line 1269 of yacc.c. */
+#line 3482 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestor ;}
+ break;
+
+ case 307:
+/* Line 1269 of yacc.c. */
+#line 3483 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAttribute ;}
+ break;
+
+ case 308:
+/* Line 1269 of yacc.c. */
+#line 3484 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisChild ;}
+ break;
+
+ case 309:
+/* Line 1269 of yacc.c. */
+#line 3485 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendantOrSelf;}
+ break;
+
+ case 310:
+/* Line 1269 of yacc.c. */
+#line 3486 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendant ;}
+ break;
+
+ case 311:
+/* Line 1269 of yacc.c. */
+#line 3487 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowing ;}
+ break;
+
+ case 312:
+/* Line 1269 of yacc.c. */
+#line 3488 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPreceding ;}
+ break;
+
+ case 313:
+/* Line 1269 of yacc.c. */
+#line 3489 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowingSibling;}
+ break;
+
+ case 314:
+/* Line 1269 of yacc.c. */
+#line 3490 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPrecedingSibling;}
+ break;
+
+ case 315:
+/* Line 1269 of yacc.c. */
+#line 3491 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisParent ;}
+ break;
+
+ case 316:
+/* Line 1269 of yacc.c. */
+#line 3492 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisSelf ;}
+ break;
+
+ case 317:
+/* Line 1269 of yacc.c. */
+#line 3495 "querytransformparser.ypp"
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 318:
+/* Line 1269 of yacc.c. */
+#line 3499 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, (yyloc));
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(3) - (3)].itemType)), (yyloc), parseInfo);
+
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 319:
+/* Line 1269 of yacc.c. */
+#line 3506 "querytransformparser.ypp"
+ {
+ ItemType::Ptr nodeTest;
+
+ if(parseInfo->isParsingPattern && *(yyvsp[(1) - (1)].itemType) == *BuiltinTypes::node)
+ nodeTest = BuiltinTypes::xsltNodeTest;
+ else
+ nodeTest = (yyvsp[(1) - (1)].itemType);
+
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisChild, nodeTest), (yyloc), parseInfo);
+ }
+ break;
+
+ case 320:
+/* Line 1269 of yacc.c. */
+#line 3517 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(1) - (1)].itemType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 322:
+/* Line 1269 of yacc.c. */
+#line 3524 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), (yyloc), parseInfo);
+ }
+ break;
+
+ case 324:
+/* Line 1269 of yacc.c. */
+#line 3530 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ }
+ break;
+
+ case 325:
+/* Line 1269 of yacc.c. */
+#line 3535 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(parseInfo->nodeTestSource, (yyvsp[(1) - (1)].qName));
+ }
+ break;
+
+ case 327:
+/* Line 1269 of yacc.c. */
+#line 3541 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = parseInfo->nodeTestSource;
+ }
+ break;
+
+ case 328:
+/* Line 1269 of yacc.c. */
+#line 3545 "querytransformparser.ypp"
+ {
+ const NamePool::Ptr np(parseInfo->staticContext->namePool());
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ const QXmlName::NamespaceCode ns(QNameConstructor::namespaceForPrefix(np->allocatePrefix((yyvsp[(1) - (1)].sval)), parseInfo->staticContext, &ryy));
+
+ (yyval.itemType) = NamespaceNameTest::create(parseInfo->nodeTestSource, ns);
+ }
+ break;
+
+ case 329:
+/* Line 1269 of yacc.c. */
+#line 3554 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(1) - (1)].sval));
+ (yyval.itemType) = LocalNameTest::create(parseInfo->nodeTestSource, c);
+ }
+ break;
+
+ case 331:
+/* Line 1269 of yacc.c. */
+#line 3562 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr), parseInfo->staticContext, fromYYLTYPE((yylsp[(4) - (4)]), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 339:
+/* Line 1269 of yacc.c. */
+#line 3575 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ApplyTemplate(parseInfo->modeFor((yyvsp[(2) - (5)].qName)),
+ parseInfo->templateWithParams,
+ parseInfo->modeFor(QXmlName(StandardNamespaces::InternalXSLT,
+ StandardLocalNames::Default))),
+ (yylsp[(1) - (5)]), parseInfo);
+ parseInfo->templateWithParametersHandled();
+ }
+ break;
+
+ case 341:
+/* Line 1269 of yacc.c. */
+#line 3586 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Literal(AtomicString::fromValue((yyvsp[(1) - (1)].sval))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 342:
+/* Line 1269 of yacc.c. */
+#line 3591 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = createNumericLiteral<Double>((yyvsp[(1) - (1)].sval), (yyloc), parseInfo);
+ }
+ break;
+
+ case 343:
+/* Line 1269 of yacc.c. */
+#line 3596 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = createNumericLiteral<Numeric>((yyvsp[(1) - (1)].sval), (yyloc), parseInfo);
+ }
+ break;
+
+ case 344:
+/* Line 1269 of yacc.c. */
+#line 3602 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = resolveVariable((yyvsp[(2) - (2)].qName), (yyloc), parseInfo, false);
+ }
+ break;
+
+ case 345:
+/* Line 1269 of yacc.c. */
+#line 3608 "querytransformparser.ypp"
+ {
+ /* See: http://www.w3.org/TR/xpath20/#id-variables */
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(QString(), (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 346:
+/* Line 1269 of yacc.c. */
+#line 3613 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(1) - (1)].qName);
+ }
+ break;
+
+ case 347:
+/* Line 1269 of yacc.c. */
+#line 3618 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 348:
+/* Line 1269 of yacc.c. */
+#line 3623 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new EmptySequence, (yyloc), parseInfo);
+ }
+ break;
+
+ case 349:
+/* Line 1269 of yacc.c. */
+#line 3629 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ContextItem(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 350:
+/* Line 1269 of yacc.c. */
+#line 3634 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 351:
+/* Line 1269 of yacc.c. */
+#line 3639 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ if(XPathHelper::isReservedNamespace((yyvsp[(1) - (4)].qName).namespaceURI()) || (yyvsp[(1) - (4)].qName).namespaceURI() == StandardNamespaces::InternalXSLT)
+ { /* We got a call to a builtin function. */
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ const Expression::Ptr
+ func(parseInfo->staticContext->
+ functionSignatures()->createFunctionCall((yyvsp[(1) - (4)].qName), (yyvsp[(3) - (4)].expressionList), parseInfo->staticContext, &ryy));
+
+ if(func)
+ (yyval.expr) = create(func, (yyloc), parseInfo);
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function with name %1 is available.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(1) - (4)].qName))),
+ ReportContext::XPST0017, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ else /* It's a call to a function created with 'declare function'.*/
+ {
+ (yyval.expr) = create(new UserFunctionCallsite((yyvsp[(1) - (4)].qName), (yyvsp[(3) - (4)].expressionList).count()), (yyloc), parseInfo);
+
+ (yyval.expr)->setOperands((yyvsp[(3) - (4)].expressionList));
+ parseInfo->userFunctionCallsites.append((yyval.expr));
+ }
+ }
+ break;
+
+ case 352:
+/* Line 1269 of yacc.c. */
+#line 3668 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ }
+ break;
+
+ case 353:
+/* Line 1269 of yacc.c. */
+#line 3673 "querytransformparser.ypp"
+ {
+ Expression::List list;
+ list.append((yyvsp[(1) - (1)].expr));
+ (yyval.expressionList) = list;
+ }
+ break;
+
+ case 355:
+/* Line 1269 of yacc.c. */
+#line 3682 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 360:
+/* Line 1269 of yacc.c. */
+#line 3726 "querytransformparser.ypp"
+ {
+ (yyval.enums.tokenizerPosition) = parseInfo->tokenizer->commenceScanOnly();
+ parseInfo->scanOnlyStack.push(true);
+ }
+ break;
+
+ case 361:
+/* Line 1269 of yacc.c. */
+#line 3735 "querytransformparser.ypp"
+ {
+ ++parseInfo->elementConstructorDepth;
+ Expression::List constructors;
+
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+
+ /* Fix up attributes and namespace declarations. */
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = (yyvsp[(4) - (4)].attributeHolders).size();
+ QSet<QXmlName::PrefixCode> usedDeclarations;
+
+ /* Whether xmlns="" has been encountered. */
+ bool hasDefaultDeclaration = false;
+
+ /* For each attribute & namespace declaration, do: */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName((yyvsp[(4) - (4)].attributeHolders).at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+
+ /* This can seem a bit weird. However, this name is ending up in a QXmlName
+ * which consider its prefix a... prefix. So, a namespace binding name can in some cases
+ * be a local name, but that's just as the initial syntactical construct. */
+ const QXmlName::LocalNameCode localName = namePool->allocatePrefix(strLocalName);
+
+ /* Not that localName is "foo" in "xmlns:foo" and that prefix is "xmlns". */
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardPrefixes::xmlns))
+ {
+ if(localName == StandardPrefixes::xmlns)
+ hasDefaultDeclaration = true;
+
+ /* We have a namespace declaration. */
+
+ const Expression::Ptr nsExpr((yyvsp[(4) - (4)].attributeHolders).at(i).second);
+
+ const QString strNamespace(nsExpr->is(Expression::IDEmptySequence) ? QString() : nsExpr->as<Literal>()->item().stringValue());
+
+ const QXmlName::NamespaceCode ns = namePool->allocateNamespace(strNamespace);
+
+ if(ns == StandardNamespaces::empty)
+ {
+ if(localName != StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI cannot be the empty string when binding to a prefix, %1.")
+ .arg(formatURI(strPrefix)),
+ ReportContext::XQST0085, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ else if(!AnyURI::isValid(strNamespace))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid namespace URI.").arg(formatURI(strNamespace)),
+ ReportContext::XQST0022, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(prefix == StandardPrefixes::xmlns && localName == StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to bind to the prefix %1")
+ .arg(formatKeyword("xmlns")),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(ns == StandardNamespaces::xml && localName != StandardPrefixes::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml)))
+ .arg(formatKeyword("xml")),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(localName == StandardPrefixes::xml && ns != StandardNamespaces::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml))),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ QXmlName nb;
+
+ if(localName == StandardPrefixes::xmlns)
+ nb = QXmlName(ns, StandardLocalNames::empty);
+ else
+ nb = QXmlName(ns, StandardLocalNames::empty, localName);
+
+ if(usedDeclarations.contains(nb.prefix()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Two namespace declaration attributes have the same name: %1.")
+ .arg(formatKeyword(namePool->stringForPrefix(nb.prefix()))),
+ ReportContext::XQST0071, fromYYLTYPE((yyloc), parseInfo));
+
+ }
+ else
+ usedDeclarations.insert(nb.prefix());
+
+ /* If the user has bound the XML namespace correctly, we in either
+ * case don't want to output it.
+ *
+ * We only have to check the namespace parts since the above checks has ensured
+ * consistency in the prefix parts. */
+ if(ns != StandardNamespaces::xml)
+ {
+ /* We don't want default namespace declarations when the
+ * default namespace already is empty. */
+ if(!(ns == StandardNamespaces::empty &&
+ localName == StandardNamespaces::xmlns &&
+ resolver->lookupNamespaceURI(StandardPrefixes::empty) == StandardNamespaces::empty))
+ {
+ constructors.append(create(new NamespaceConstructor(nb), (yyloc), parseInfo));
+ resolver->addBinding(nb);
+ }
+ }
+ }
+ }
+
+ if(parseInfo->elementConstructorDepth == 1 && !hasDefaultDeclaration)
+ {
+ /* TODO But mostly this isn't needed, since the default element
+ * namespace is empty? How does this at all work? */
+ const QXmlName def(resolver->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ constructors.append(create(new NamespaceConstructor(def), (yyloc), parseInfo));
+ }
+
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ (yyval.expressionList) = constructors;
+
+ /* Resolve the name of the element, now that the namespace attributes are read. */
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ const QXmlName ele = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>((yyvsp[(2) - (4)].sval), parseInfo->staticContext, resolver, &ryy);
+ parseInfo->tagStack.push(ele);
+ }
+
+ parseInfo->tokenizer->resumeTokenizationFrom((yyvsp[(3) - (4)].enums.tokenizerPosition));
+ }
+ break;
+
+ case 362:
+/* Line 1269 of yacc.c. */
+#line 3881 "querytransformparser.ypp"
+ {
+ /* We add the content constructor after the attribute constructors. This might result
+ * in nested ExpressionSequences, but it will be optimized away later on. */
+
+ Expression::List attributes((yyvsp[(5) - (8)].expressionList));
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = (yyvsp[(7) - (8)].attributeHolders).size();
+ QSet<QXmlName> declaredAttributes;
+ declaredAttributes.reserve(len);
+
+ /* For each namespace, resolve its name(now that we have resolved the namespace declarations) and
+ * turn it into an attribute constructor. */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName((yyvsp[(7) - (8)].attributeHolders).at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+ const QXmlName::LocalNameCode localName = namePool->allocateLocalName(strLocalName);
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardLocalNames::xmlns))
+ {
+ const Expression::ID id = (yyvsp[(7) - (8)].attributeHolders).at(i).second->id();
+
+ if(id == Expression::IDStringValue || id == Expression::IDEmptySequence)
+ {
+ /* It's a namespace declaration, and we've already handled those above. */
+ continue;
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI must be a constant and cannot "
+ "use enclosed expressions."),
+ ReportContext::XQST0022, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ }
+ else
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+ const QXmlName att = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>((yyvsp[(7) - (8)].attributeHolders).at(i).first, parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(),
+ &ryy, true);
+ if(declaredAttributes.contains(att))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An attribute with name %1 has already appeared on this element.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), att)),
+ ReportContext::XQST0040, fromYYLTYPE((yyloc), parseInfo));
+
+ }
+ else
+ declaredAttributes.insert(att);
+
+ /* wrapLiteral() needs the SourceLocationReflection of the AttributeConstructor, but
+ * it's unknown inside the arguments to its constructor. Hence we have to do this workaround of setting
+ * it twice.
+ *
+ * The AttributeConstructor's arguments are just dummies. */
+ const Expression::Ptr ctor(create(new AttributeConstructor((yyvsp[(7) - (8)].attributeHolders).at(i).second, (yyvsp[(7) - (8)].attributeHolders).at(i).second), (yyloc), parseInfo));
+
+ Expression::List ops;
+ ops.append(wrapLiteral(toItem(QNameValue::fromValue(namePool, att)), parseInfo->staticContext, ctor.data()));
+ ops.append((yyvsp[(7) - (8)].attributeHolders).at(i).second);
+ ctor->setOperands(ops);
+
+ attributes.append(ctor);
+ }
+ }
+
+ Expression::Ptr contentOp;
+
+ if(attributes.isEmpty())
+ contentOp = (yyvsp[(8) - (8)].expr);
+ else
+ {
+ attributes.append((yyvsp[(8) - (8)].expr));
+ contentOp = create(new ExpressionSequence(attributes), (yyloc), parseInfo);
+ }
+
+ const Expression::Ptr name(create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), parseInfo->tagStack.top()))), (yyloc), parseInfo));
+ (yyval.expr) = create(new ElementConstructor(name, contentOp, parseInfo->isXSLT()), (yyloc), parseInfo);
+
+ /* Restore the old context. We don't want the namespaces
+ * to be in-scope for expressions appearing after the
+ * element they appeared on. */
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ parseInfo->tagStack.pop();
+
+ --parseInfo->elementConstructorDepth;
+ }
+ break;
+
+ case 363:
+/* Line 1269 of yacc.c. */
+#line 3977 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new EmptySequence(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 364:
+/* Line 1269 of yacc.c. */
+#line 3981 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(4) - (5)].qName).isLexicallyEqual(parseInfo->tagStack.top()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A direct element constructor is not "
+ "well-formed. %1 is ended with %2.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical(parseInfo->tagStack.top())),
+ formatKeyword(parseInfo->staticContext->namePool()->toLexical((yyvsp[(4) - (5)].qName)))),
+ ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if((yyvsp[(2) - (5)].expressionList).isEmpty())
+ (yyval.expr) = create(new EmptySequence(), (yyloc), parseInfo);
+ else if((yyvsp[(2) - (5)].expressionList).size() == 1)
+ (yyval.expr) = (yyvsp[(2) - (5)].expressionList).first();
+ else
+ (yyval.expr) = create(new ExpressionSequence((yyvsp[(2) - (5)].expressionList)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 365:
+/* Line 1269 of yacc.c. */
+#line 4000 "querytransformparser.ypp"
+ {
+ (yyval.attributeHolders) = AttributeHolderVector();
+ }
+ break;
+
+ case 366:
+/* Line 1269 of yacc.c. */
+#line 4004 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (2)].attributeHolders).append((yyvsp[(2) - (2)].attributeHolder));
+ (yyval.attributeHolders) = (yyvsp[(1) - (2)].attributeHolders);
+ }
+ break;
+
+ case 367:
+/* Line 1269 of yacc.c. */
+#line 4010 "querytransformparser.ypp"
+ {
+ (yyval.attributeHolder) = qMakePair((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr));
+ }
+ break;
+
+ case 368:
+/* Line 1269 of yacc.c. */
+#line 4015 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 369:
+/* Line 1269 of yacc.c. */
+#line 4020 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 370:
+/* Line 1269 of yacc.c. */
+#line 4025 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ }
+ break;
+
+ case 371:
+/* Line 1269 of yacc.c. */
+#line 4029 "querytransformparser.ypp"
+ {
+ Expression::Ptr content((yyvsp[(1) - (2)].expr));
+
+ if(parseInfo->isBackwardsCompat.top())
+ content = create(GenericPredicate::createFirstItem(content), (yyloc), parseInfo);
+
+ (yyvsp[(2) - (2)].expressionList).prepend(createSimpleContent(content, (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(2) - (2)].expressionList);
+ }
+ break;
+
+ case 372:
+/* Line 1269 of yacc.c. */
+#line 4039 "querytransformparser.ypp"
+ {
+ (yyvsp[(2) - (2)].expressionList).prepend(create(new Literal(AtomicString::fromValue((yyvsp[(1) - (2)].sval))), (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(2) - (2)].expressionList);
+ }
+ break;
+
+ case 373:
+/* Line 1269 of yacc.c. */
+#line 4045 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ break;
+
+ case 374:
+/* Line 1269 of yacc.c. */
+#line 4050 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (2)].expressionList).append((yyvsp[(2) - (2)].expr));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ break;
+
+ case 375:
+/* Line 1269 of yacc.c. */
+#line 4056 "querytransformparser.ypp"
+ {
+ if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip &&
+ XPathHelper::isWhitespaceOnly((yyvsp[(2) - (2)].sval)))
+ {
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ }
+ else
+ {
+ (yyvsp[(1) - (2)].expressionList).append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ }
+ break;
+
+ case 376:
+/* Line 1269 of yacc.c. */
+#line 4070 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (2)].expressionList).append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ break;
+
+ case 377:
+/* Line 1269 of yacc.c. */
+#line 4076 "querytransformparser.ypp"
+ {
+ /* We insert a text node constructor that send an empty text node between
+ * the two enclosed expressions, in order to ensure that no space is inserted.
+ *
+ * However, we only do it when we have no node constructors. */
+ if(parseInfo->isPreviousEnclosedExpr &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches((yyvsp[(2) - (2)].expr)->staticType()->itemType()) &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches((yyvsp[(1) - (2)].expressionList).last()->staticType()->itemType()))
+ (yyvsp[(1) - (2)].expressionList).append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue(QString())), (yyloc), parseInfo)), (yyloc), parseInfo));
+ else
+ parseInfo->isPreviousEnclosedExpr = true;
+
+ (yyvsp[(1) - (2)].expressionList).append(createCopyOf((yyvsp[(2) - (2)].expr), parseInfo, (yyloc)));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ }
+ break;
+
+ case 378:
+/* Line 1269 of yacc.c. */
+#line 4093 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CommentConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 379:
+/* Line 1269 of yacc.c. */
+#line 4098 "querytransformparser.ypp"
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+ NCNameConstructor::validateTargetName<StaticContext::Ptr,
+ ReportContext::XPST0003,
+ ReportContext::XPST0003>((yyvsp[(2) - (3)].sval),
+ parseInfo->staticContext, &ryy);
+
+ (yyval.expr) = create(new ProcessingInstructionConstructor(
+ create(new Literal(AtomicString::fromValue((yyvsp[(2) - (3)].sval))), (yyloc), parseInfo),
+ create(new Literal(AtomicString::fromValue((yyvsp[(3) - (3)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 387:
+/* Line 1269 of yacc.c. */
+#line 4119 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].enums.Bool));
+
+ (yyval.expr) = create(new DocumentConstructor((yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 388:
+/* Line 1269 of yacc.c. */
+#line 4126 "querytransformparser.ypp"
+ {
+ /* This value is incremented before the action below is executed. */
+ ++parseInfo->elementConstructorDepth;
+ }
+ break;
+
+ case 389:
+/* Line 1269 of yacc.c. */
+#line 4131 "querytransformparser.ypp"
+ {
+ Q_ASSERT(5);
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (5)].enums.Bool));
+
+ Expression::Ptr effExpr;
+
+ if((yyvsp[(5) - (5)].expr))
+ effExpr = createCopyOf((yyvsp[(5) - (5)].expr), parseInfo, (yyloc));
+ else
+ effExpr = create(new EmptySequence(), (yyloc), parseInfo);
+
+ const QXmlName::NamespaceCode ns = parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty);
+
+ /* Ensure the default namespace gets counted as an in-scope binding, if such a one exists. If we're
+ * a child of another constructor, it has already been done. */
+ if(parseInfo->elementConstructorDepth == 1 && ns != StandardNamespaces::empty)
+ {
+ Expression::List exprList;
+
+ /* We append the namespace constructor before the body, in order to
+ * comply with QAbstractXmlPushHandler's contract. */
+ const QXmlName def(parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ exprList.append(create(new NamespaceConstructor(def), (yyloc), parseInfo));
+
+ exprList.append(effExpr);
+
+ effExpr = create(new ExpressionSequence(exprList), (yyloc), parseInfo);
+ }
+
+ --parseInfo->elementConstructorDepth;
+ (yyval.expr) = create(new ElementConstructor((yyvsp[(3) - (5)].expr), effExpr, parseInfo->isXSLT()), (yyloc), parseInfo);
+ }
+ break;
+
+ case 390:
+/* Line 1269 of yacc.c. */
+#line 4165 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = false;
+ }
+ break;
+
+ case 391:
+/* Line 1269 of yacc.c. */
+#line 4169 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = true;
+ }
+ break;
+
+ case 392:
+/* Line 1269 of yacc.c. */
+#line 4177 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (4)].enums.Bool));
+
+ const Expression::Ptr name(create(new AttributeNameValidator((yyvsp[(3) - (4)].expr)), (yyloc), parseInfo));
+
+ if((yyvsp[(4) - (4)].expr))
+ (yyval.expr) = create(new AttributeConstructor(name, createSimpleContent((yyvsp[(4) - (4)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ else
+ (yyval.expr) = create(new AttributeConstructor(name, create(new EmptySequence(), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 393:
+/* Line 1269 of yacc.c. */
+#line 4189 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new TextNodeConstructor(createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 394:
+/* Line 1269 of yacc.c. */
+#line 4194 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].enums.Bool));
+
+ (yyval.expr) = create(new CommentConstructor(createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 395:
+/* Line 1269 of yacc.c. */
+#line 4201 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].expr));
+
+ if((yyvsp[(3) - (3)].expr))
+ {
+ (yyval.expr) = create(new ProcessingInstructionConstructor((yyvsp[(2) - (3)].expr), createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ else
+ (yyval.expr) = create(new ProcessingInstructionConstructor((yyvsp[(2) - (3)].expr), create(new EmptySequence(), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 396:
+/* Line 1269 of yacc.c. */
+#line 4212 "querytransformparser.ypp"
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 397:
+/* Line 1269 of yacc.c. */
+#line 4216 "querytransformparser.ypp"
+ {
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 398:
+/* Line 1269 of yacc.c. */
+#line 4219 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), (yyvsp[(2) - (3)].qName)))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 400:
+/* Line 1269 of yacc.c. */
+#line 4225 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), (yyvsp[(1) - (1)].qName)))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 402:
+/* Line 1269 of yacc.c. */
+#line 4231 "querytransformparser.ypp"
+ {
+ if(BuiltinTypes::xsQName->xdtTypeMatches((yyvsp[(1) - (1)].expr)->staticType()->itemType()))
+ (yyval.expr) = (yyvsp[(1) - (1)].expr);
+ else
+ {
+ (yyval.expr) = create(new QNameConstructor((yyvsp[(1) - (1)].expr),
+ parseInfo->staticContext->namespaceBindings()),
+ (yyloc), parseInfo);
+ }
+ }
+ break;
+
+ case 403:
+/* Line 1269 of yacc.c. */
+#line 4246 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(1) - (1)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 404:
+/* Line 1269 of yacc.c. */
+#line 4250 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new NCNameConstructor((yyvsp[(1) - (1)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 405:
+/* Line 1269 of yacc.c. */
+#line 4259 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ComputedNamespaceConstructor((yyvsp[(2) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+}
+ break;
+
+ case 406:
+/* Line 1269 of yacc.c. */
+#line 4264 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (1)].itemType), Cardinality::exactlyOne());
+ }
+ break;
+
+ case 407:
+/* Line 1269 of yacc.c. */
+#line 4268 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), Cardinality::zeroOrOne());
+ }
+ break;
+
+ case 408:
+/* Line 1269 of yacc.c. */
+#line 4273 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = CommonSequenceTypes::ZeroOrMoreItems;
+ }
+ break;
+
+ case 409:
+/* Line 1269 of yacc.c. */
+#line 4277 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = (yyvsp[(2) - (2)].sequenceType);
+ }
+ break;
+
+ case 410:
+/* Line 1269 of yacc.c. */
+#line 4282 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), (yyvsp[(2) - (2)].cardinality));
+ }
+ break;
+
+ case 411:
+/* Line 1269 of yacc.c. */
+#line 4287 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = CommonSequenceTypes::Empty;
+ }
+ break;
+
+ case 412:
+/* Line 1269 of yacc.c. */
+#line 4291 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::exactlyOne();}
+ break;
+
+ case 413:
+/* Line 1269 of yacc.c. */
+#line 4292 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::oneOrMore();}
+ break;
+
+ case 414:
+/* Line 1269 of yacc.c. */
+#line 4293 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::zeroOrMore();}
+ break;
+
+ case 415:
+/* Line 1269 of yacc.c. */
+#line 4294 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::zeroOrOne();}
+ break;
+
+ case 419:
+/* Line 1269 of yacc.c. */
+#line 4300 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::item;
+ }
+ break;
+
+ case 420:
+/* Line 1269 of yacc.c. */
+#line 4305 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(1) - (1)].qName)));
+
+ if(!t)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name %1 does not refer to any schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(1) - (1)].qName))), ReportContext::XPST0051, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(t))
+ (yyval.itemType) = AtomicType::Ptr(t);
+ else
+ {
+ /* Try to give an intelligent message. */
+ if(t->isComplexType())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an complex type. Casting to complex "
+ "types is not possible. However, casting "
+ "to atomic types such as %2 works.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t))
+ .arg(formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsInteger)),
+ ReportContext::XPST0051, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not an atomic type. Casting "
+ "is only possible to atomic types.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t)),
+ ReportContext::XPST0051, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ }
+ break;
+
+ case 428:
+/* Line 1269 of yacc.c. */
+#line 4349 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::node;
+ }
+ break;
+
+ case 429:
+/* Line 1269 of yacc.c. */
+#line 4354 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::document;
+ }
+ break;
+
+ case 430:
+/* Line 1269 of yacc.c. */
+#line 4359 "querytransformparser.ypp"
+ {
+ // TODO support for document element testing
+ (yyval.itemType) = BuiltinTypes::document;
+ }
+ break;
+
+ case 433:
+/* Line 1269 of yacc.c. */
+#line 4368 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::text;
+ }
+ break;
+
+ case 434:
+/* Line 1269 of yacc.c. */
+#line 4373 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::comment;
+ }
+ break;
+
+ case 435:
+/* Line 1269 of yacc.c. */
+#line 4378 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::pi;
+ }
+ break;
+
+ case 436:
+/* Line 1269 of yacc.c. */
+#line 4383 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(3) - (4)].sval)));
+ }
+ break;
+
+ case 437:
+/* Line 1269 of yacc.c. */
+#line 4388 "querytransformparser.ypp"
+ {
+ if(QXmlUtils::isNCName((yyvsp[(3) - (4)].sval)))
+ {
+ (yyval.itemType) = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(3) - (4)].sval)));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid name for a "
+ "processing-instruction.")
+ .arg(formatKeyword((yyvsp[(3) - (4)].sval))),
+ ReportContext::XPTY0004,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 440:
+/* Line 1269 of yacc.c. */
+#line 4407 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 441:
+/* Line 1269 of yacc.c. */
+#line 4412 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 442:
+/* Line 1269 of yacc.c. */
+#line 4417 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(BuiltinTypes::attribute, (yyvsp[(3) - (4)].qName));
+ }
+ break;
+
+ case 443:
+/* Line 1269 of yacc.c. */
+#line 4421 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (6)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (6)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 444:
+/* Line 1269 of yacc.c. */
+#line 4433 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (6)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (6)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 445:
+/* Line 1269 of yacc.c. */
+#line 4446 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (4)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ (yyval.itemType).reset();
+ }
+ break;
+
+ case 446:
+/* Line 1269 of yacc.c. */
+#line 4456 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::element;
+ }
+ break;
+
+ case 447:
+/* Line 1269 of yacc.c. */
+#line 4461 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::element;
+ }
+ break;
+
+ case 448:
+/* Line 1269 of yacc.c. */
+#line 4466 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(BuiltinTypes::element, (yyvsp[(3) - (4)].qName));
+ }
+ break;
+
+ case 449:
+/* Line 1269 of yacc.c. */
+#line 4471 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (7)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(unknownType()
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (7)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 450:
+/* Line 1269 of yacc.c. */
+#line 4485 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (7)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an unknown schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (7)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 453:
+/* Line 1269 of yacc.c. */
+#line 4502 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (4)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ (yyval.itemType).reset();
+ }
+ break;
+
+ case 455:
+/* Line 1269 of yacc.c. */
+#line 4514 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 457:
+/* Line 1269 of yacc.c. */
+#line 4526 "querytransformparser.ypp"
+ {
+ if(parseInfo->nodeTestSource == BuiltinTypes::element)
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), (yyvsp[(1) - (1)].sval));
+ else
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 462:
+/* Line 1269 of yacc.c. */
+#line 4540 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 463:
+/* Line 1269 of yacc.c. */
+#line 4544 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, (yyvsp[(2) - (2)].sval));
+ }
+ break;
+
+ case 466:
+/* Line 1269 of yacc.c. */
+#line 4552 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in "
+ "a namespace."),
+ ReportContext::XPST0081, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 469:
+/* Line 1269 of yacc.c. */
+#line 4562 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ }
+ break;
+
+ case 470:
+/* Line 1269 of yacc.c. */
+#line 4566 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ }
+ break;
+
+ case 471:
+/* Line 1269 of yacc.c. */
+#line 4571 "querytransformparser.ypp"
+ {
+
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ (yyval.qName) = QNameConstructor::
+ expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>((yyvsp[(1) - (1)].sval), parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(), &ryy);
+
+ }
+ break;
+
+ case 472:
+/* Line 1269 of yacc.c. */
+#line 4583 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->fromClarkName((yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+
+/* Line 1269 of yacc.c. */
+#line 7763 "qquerytransformparser.cpp"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, parseInfo, YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (&yylloc, parseInfo, yymsg);
+ }
+ else
+ {
+ yyerror (&yylloc, parseInfo, YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+ yyerror_range[0] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc, parseInfo);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[0] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[0] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp, parseInfo);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+ yyerror_range[1] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, parseInfo, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc, parseInfo);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp, parseInfo);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+/* Line 1486 of yacc.c. */
+#line 4587 "querytransformparser.ypp"
+
+
+QString Tokenizer::tokenToString(const Token &token)
+{
+ switch(token.type)
+ {
+ case NCNAME:
+ /* Fallthrough. */
+ case QNAME:
+ /* Fallthrough. */
+ case NUMBER:
+ /* Fallthrough. */
+ case XPATH2_NUMBER:
+ return token.value;
+ case STRING_LITERAL:
+ return QLatin1Char('"') + token.value + QLatin1Char('"');
+ default:
+ {
+ const QString raw(QString::fromLatin1(yytname[YYTRANSLATE(token.type)]));
+
+ /* Remove the quotes. */
+ if(raw.at(0) == QLatin1Char('"') && raw.length() > 1)
+ return raw.mid(1, raw.length() - 2);
+ else
+ return raw;
+ }
+ }
+}
+
+} /* namespace Patternist */
+
+QT_END_NAMESPACE
+
+// vim: et:ts=4:sw=4:sts=4:syntax=yacc
+
diff --git a/src/xmlpatterns/parser/qquerytransformparser_p.h b/src/xmlpatterns/parser/qquerytransformparser_p.h
new file mode 100644
index 0000000..a4c1191
--- /dev/null
+++ b/src/xmlpatterns/parser/qquerytransformparser_p.h
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
+/* A Bison parser, made by GNU Bison 2.3a. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* These tokens are defined to nothing on Windows because they're
+ * used in their documentation parser, for use in things like:
+ *
+ * int foo(IN char* name, OUT char* path);
+ *
+ * Hence this un-break fix. Note that this file was auto generated. */
+#ifdef IN
+# undef IN
+#endif
+#ifdef INSTANCE
+# undef INSTANCE
+#endif
+#ifdef STRICT
+# undef STRICT
+#endif
+#ifdef SELF
+# undef SELF
+#endif
+/* These tokens are defined in VxWorks kernel mode
+ *
+ * Hence this un-break fix. Note that this file was auto generated. */
+#ifdef ERROR
+# undef ERROR
+#endif
+#ifdef IMPORT
+# undef IMPORT
+#endif
+#ifdef MAP
+# undef MAP
+#endif
+
+/* These tokens are defined to nothing on Windows because they're
+ * used in their documentation parser, for use in things like:
+ *
+ * int foo(IN char* name, OUT char* path);
+ *
+ * Hence this un-break fix. Note that this file was auto generated. */
+#ifdef IN
+# undef IN
+#endif
+#ifdef INSTANCE
+# undef INSTANCE
+#endif
+#ifdef STRICT
+# undef STRICT
+#endif
+#ifdef SELF
+# undef SELF
+#endif
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ END_OF_FILE = 0,
+ STRING_LITERAL = 258,
+ NON_BOUNDARY_WS = 259,
+ XPATH2_STRING_LITERAL = 260,
+ QNAME = 261,
+ NCNAME = 262,
+ CLARK_NAME = 263,
+ ANY_LOCAL_NAME = 264,
+ ANY_PREFIX = 265,
+ NUMBER = 266,
+ XPATH2_NUMBER = 267,
+ ANCESTOR = 268,
+ ANCESTOR_OR_SELF = 269,
+ AND = 270,
+ APOS = 271,
+ APPLY_TEMPLATE = 272,
+ AS = 273,
+ ASCENDING = 274,
+ ASSIGN = 275,
+ AT = 276,
+ AT_SIGN = 277,
+ ATTRIBUTE = 278,
+ AVT = 279,
+ BAR = 280,
+ BASEURI = 281,
+ BEGIN_END_TAG = 282,
+ BOUNDARY_SPACE = 283,
+ BY = 284,
+ CALL_TEMPLATE = 285,
+ CASE = 286,
+ CASTABLE = 287,
+ CAST = 288,
+ CHILD = 289,
+ COLLATION = 290,
+ COLONCOLON = 291,
+ COMMA = 292,
+ COMMENT = 293,
+ COMMENT_START = 294,
+ CONSTRUCTION = 295,
+ COPY_NAMESPACES = 296,
+ CURLY_LBRACE = 297,
+ CURLY_RBRACE = 298,
+ DECLARE = 299,
+ DEFAULT = 300,
+ DESCENDANT = 301,
+ DESCENDANT_OR_SELF = 302,
+ DESCENDING = 303,
+ DIV = 304,
+ DOCUMENT = 305,
+ DOCUMENT_NODE = 306,
+ DOLLAR = 307,
+ DOT = 308,
+ DOTDOT = 309,
+ ELEMENT = 310,
+ ELSE = 311,
+ EMPTY = 312,
+ EMPTY_SEQUENCE = 313,
+ ENCODING = 314,
+ END_SORT = 315,
+ EQ = 316,
+ ERROR = 317,
+ EVERY = 318,
+ EXCEPT = 319,
+ EXTERNAL = 320,
+ FOLLOWING = 321,
+ FOLLOWING_SIBLING = 322,
+ FOLLOWS = 323,
+ FOR_APPLY_TEMPLATE = 324,
+ FOR = 325,
+ FUNCTION = 326,
+ GE = 327,
+ G_EQ = 328,
+ G_GE = 329,
+ G_GT = 330,
+ G_LE = 331,
+ G_LT = 332,
+ G_NE = 333,
+ GREATEST = 334,
+ GT = 335,
+ IDIV = 336,
+ IF = 337,
+ IMPORT = 338,
+ INHERIT = 339,
+ IN = 340,
+ INSTANCE = 341,
+ INTERSECT = 342,
+ IS = 343,
+ ITEM = 344,
+ LAX = 345,
+ LBRACKET = 346,
+ LEAST = 347,
+ LE = 348,
+ LET = 349,
+ LPAREN = 350,
+ LT = 351,
+ MAP = 352,
+ MATCHES = 353,
+ MINUS = 354,
+ MODE = 355,
+ MOD = 356,
+ MODULE = 357,
+ NAME = 358,
+ NAMESPACE = 359,
+ NE = 360,
+ NODE = 361,
+ NO_INHERIT = 362,
+ NO_PRESERVE = 363,
+ OF = 364,
+ OPTION = 365,
+ ORDERED = 366,
+ ORDERING = 367,
+ ORDER = 368,
+ OR = 369,
+ PARENT = 370,
+ PI_START = 371,
+ PLUS = 372,
+ POSITION_SET = 373,
+ PRAGMA_END = 374,
+ PRAGMA_START = 375,
+ PRECEDES = 376,
+ PRECEDING = 377,
+ PRECEDING_SIBLING = 378,
+ PRESERVE = 379,
+ PRIORITY = 380,
+ PROCESSING_INSTRUCTION = 381,
+ QUESTION = 382,
+ QUICK_TAG_END = 383,
+ QUOTE = 384,
+ RBRACKET = 385,
+ RETURN = 386,
+ RPAREN = 387,
+ SATISFIES = 388,
+ SCHEMA_ATTRIBUTE = 389,
+ SCHEMA_ELEMENT = 390,
+ SCHEMA = 391,
+ SELF = 392,
+ SEMI_COLON = 393,
+ SLASH = 394,
+ SLASHSLASH = 395,
+ SOME = 396,
+ SORT = 397,
+ STABLE = 398,
+ STAR = 399,
+ STRICT = 400,
+ STRIP = 401,
+ SUCCESS = 402,
+ COMMENT_CONTENT = 403,
+ PI_CONTENT = 404,
+ PI_TARGET = 405,
+ XSLT_VERSION = 406,
+ TEMPLATE = 407,
+ TEXT = 408,
+ THEN = 409,
+ TO = 410,
+ TREAT = 411,
+ TUNNEL = 412,
+ TYPESWITCH = 413,
+ UNION = 414,
+ UNORDERED = 415,
+ VALIDATE = 416,
+ VARIABLE = 417,
+ VERSION = 418,
+ WHERE = 419,
+ XQUERY = 420,
+ INTERNAL = 421,
+ INTERNAL_NAME = 422,
+ CURRENT = 423
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/src/xmlpatterns/parser/qtokenizer_p.h b/src/xmlpatterns/parser/qtokenizer_p.h
new file mode 100644
index 0000000..3a50980
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenizer_p.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Tokenizer_H
+#define Patternist_Tokenizer_H
+
+#include <QPair>
+#include <QSharedData>
+#include <QString>
+#include <QUrl>
+
+#include "qparsercontext_p.h"
+#include "qtokensource_p.h"
+
+/**
+ * @file
+ * @short Contains functions and classes used by the parser and tokenizer.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ typedef QPair<QString, Expression::Ptr> AttributeHolder;
+ typedef QVector<AttributeHolder> AttributeHolderVector;
+
+ class OrderSpecTransfer
+ {
+ public:
+ typedef QList<OrderSpecTransfer> List;
+ inline OrderSpecTransfer()
+ {
+ }
+
+ inline OrderSpecTransfer(const Expression::Ptr &aExpr,
+ const OrderBy::OrderSpec aOrderSpec) : expression(aExpr),
+ orderSpec(aOrderSpec)
+ {
+ Q_ASSERT(expression);
+ }
+
+ Expression::Ptr expression;
+ OrderBy::OrderSpec orderSpec;
+ };
+
+ /**
+ * @short The value the parser, but not the tokenizers, uses for tokens and
+ * non-terminals.
+ *
+ * It is inefficient but ensures nothing leaks, by invoking C++
+ * destructors even in the cases the code throws exceptions. This might be
+ * able to be done in a more efficient way -- suggestions are welcome.
+ */
+ class TokenValue
+ {
+ public:
+ QString sval;
+
+ Expression::Ptr expr;
+ Expression::List expressionList;
+
+ Cardinality cardinality;
+ ItemType::Ptr itemType;
+ SequenceType::Ptr sequenceType;
+ FunctionArgument::List functionArguments;
+ FunctionArgument::Ptr functionArgument;
+ QVector<QXmlName> qNameVector;
+ QXmlName qName;
+ /**
+ * Holds enum values.
+ */
+ EnumUnion enums;
+
+ AttributeHolder attributeHolder;
+ AttributeHolderVector attributeHolders;
+ OrderSpecTransfer::List orderSpecs;
+ OrderSpecTransfer orderSpec;
+ };
+}
+
+QT_END_NAMESPACE
+
+/**
+ * Macro for the data type of semantic values; int by default.
+ * See section Data Types of Semantic Values.
+ */
+#define YYSTYPE QPatternist::TokenValue
+
+#include "qquerytransformparser_p.h" /* This inclusion must be after TokenValue. */
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all tokenizers.
+ *
+ * The main entry point is nextToken(), which ones calls to retrieve the stream
+ * of tokens this Tokenizer delivers.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a
+ * Tokenizer for XPath or XQuery</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Tokenizer : public TokenSource
+ {
+ public:
+ inline Tokenizer(const QUrl &queryU) : m_queryURI(queryU)
+ {
+ Q_ASSERT(queryU.isValid());
+ }
+
+ typedef QExplicitlySharedDataPointer<Tokenizer> Ptr;
+
+ /**
+ * Switches the Tokenizer to only do scanning, and returns complete
+ * strings for attribute value templates as opposed to the tokens for
+ * the contained expressions.
+ *
+ * The current position in the stream is returned. It can be used to
+ * later resume regular tokenization.
+ */
+ virtual int commenceScanOnly() = 0;
+
+ /**
+ * Resumes regular parsing from @p position. The tokenizer must be in
+ * the scan-only state, which the commenceScanOnly() call transists to.
+ *
+ * The tokenizer will return the token POSITION_SET once after this
+ * function has been called.
+ */
+ virtual void resumeTokenizationFrom(const int position) = 0;
+
+ /**
+ * @returns the URI of the resource being tokenized.
+ */
+ inline const QUrl &queryURI() const
+ {
+ return m_queryURI;
+ }
+
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo) = 0;
+
+ protected:
+ /**
+ * Returns a string representation of @p token.
+ *
+ * This function is used for debugging purposes. The implementation of
+ * this function is in querytransformparser.ypp.
+ */
+ static QString tokenToString(const Token &token);
+
+ private:
+ Q_DISABLE_COPY(Tokenizer)
+ const QUrl m_queryURI;
+ };
+
+}
+
+#undef Patternist_DEBUG_PARSER // disable it for now
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/qtokenlookup.cpp b/src/xmlpatterns/parser/qtokenlookup.cpp
new file mode 100644
index 0000000..a6ea7ed
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenlookup.cpp
@@ -0,0 +1,444 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/* C++ code produced by gperf version 3.0.3 */
+/* Command-line: gperf TokenLookup.gperf */
+/* Computed positions: -k'1,3,$' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+#line 107 "TokenLookup.gperf"
+
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+#line 101 "TokenLookup.gperf"
+struct TokenMap
+{
+ const char *name;
+ const Tokenizer::TokenType token;
+}
+
+
+/* The strings below are in UTF-16 encoding. Subsequently, each ASCII
+ * character is stored as the ASCII character, followed by a null byte.
+ * Sorted alphabetically. */;
+/* maximum key range = 228, duplicates = 0 */
+
+class TokenLookup
+{
+private:
+ static inline unsigned int hash (const char *str, unsigned int len);
+public:
+ static const struct TokenMap *value (const char *str, unsigned int len);
+};
+
+inline unsigned int
+TokenLookup::hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 25, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 0, 2, 5,
+ 25, 0, 20, 20, 35, 85, 230, 230, 40, 110,
+ 25, 65, 80, 0, 60, 5, 10, 0, 55, 5,
+ 20, 0, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230
+ };
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[2]];
+ /*FALLTHROUGH*/
+ case 2:
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
+}
+
+const struct TokenMap *
+TokenLookup::value (register const char *str, register unsigned int len)
+{
+ enum
+ {
+ TOTAL_KEYWORDS = 99,
+ MIN_WORD_LENGTH = 2,
+ MAX_WORD_LENGTH = 22,
+ MIN_HASH_VALUE = 2,
+ MAX_HASH_VALUE = 229
+ };
+
+ static const struct TokenMap wordlist[] =
+ {
+ {"",ERROR}, {"",ERROR},
+#line 152 "TokenLookup.gperf"
+ {"eq", EQ},
+ {"",ERROR},
+#line 130 "TokenLookup.gperf"
+ {"by", BY},
+#line 153 "TokenLookup.gperf"
+ {"every", EVERY},
+ {"",ERROR},
+#line 123 "TokenLookup.gperf"
+ {"as", AS},
+ {"",ERROR},
+#line 148 "TokenLookup.gperf"
+ {"else", ELSE},
+#line 217 "TokenLookup.gperf"
+ {"where", WHERE},
+#line 204 "TokenLookup.gperf"
+ {"stable", STABLE},
+#line 126 "TokenLookup.gperf"
+ {"at", AT},
+ {"",ERROR},
+#line 131 "TokenLookup.gperf"
+ {"case", CASE},
+ {"",ERROR},
+#line 129 "TokenLookup.gperf"
+ {"boundary-space", BOUNDARY_SPACE},
+#line 147 "TokenLookup.gperf"
+ {"element", ELEMENT},
+#line 132 "TokenLookup.gperf"
+ {"castable", CASTABLE},
+#line 127 "TokenLookup.gperf"
+ {"attribute", ATTRIBUTE},
+ {"",ERROR},
+#line 154 "TokenLookup.gperf"
+ {"except", EXCEPT},
+#line 161 "TokenLookup.gperf"
+ {"ge", GE},
+ {"",ERROR},
+#line 133 "TokenLookup.gperf"
+ {"cast", CAST},
+#line 210 "TokenLookup.gperf"
+ {"treat", TREAT},
+#line 218 "TokenLookup.gperf"
+ {"xquery", XQUERY},
+#line 181 "TokenLookup.gperf"
+ {"ne", NE},
+ {"",ERROR},
+#line 198 "TokenLookup.gperf"
+ {"satisfies", SATISFIES},
+ {"",ERROR}, {"",ERROR},
+#line 163 "TokenLookup.gperf"
+ {"gt", GT},
+#line 151 "TokenLookup.gperf"
+ {"encoding", ENCODING},
+#line 124 "TokenLookup.gperf"
+ {"ascending", ASCENDING},
+ {"",ERROR},
+#line 125 "TokenLookup.gperf"
+ {"assign", ASSIGN},
+#line 139 "TokenLookup.gperf"
+ {"declare", DECLARE},
+#line 162 "TokenLookup.gperf"
+ {"greatest", GREATEST},
+#line 208 "TokenLookup.gperf"
+ {"then", THEN},
+ {"",ERROR},
+#line 121 "TokenLookup.gperf"
+ {"ancestor-or-self", ANCESTOR_OR_SELF},
+#line 175 "TokenLookup.gperf"
+ {"le", LE},
+#line 146 "TokenLookup.gperf"
+ {"document-node", DOCUMENT_NODE},
+#line 207 "TokenLookup.gperf"
+ {"text", TEXT},
+ {"",ERROR},
+#line 201 "TokenLookup.gperf"
+ {"schema", SCHEMA},
+ {"",ERROR},
+#line 145 "TokenLookup.gperf"
+ {"document", DOCUMENT},
+ {"",ERROR},
+#line 141 "TokenLookup.gperf"
+ {"descendant", DESCENDANT},
+ {"",ERROR},
+#line 177 "TokenLookup.gperf"
+ {"lt", LT},
+#line 122 "TokenLookup.gperf"
+ {"and", AND},
+#line 182 "TokenLookup.gperf"
+ {"node", NODE},
+#line 174 "TokenLookup.gperf"
+ {"least", LEAST},
+#line 199 "TokenLookup.gperf"
+ {"schema-attribute", SCHEMA_ATTRIBUTE},
+ {"",ERROR},
+#line 155 "TokenLookup.gperf"
+ {"external", EXTERNAL},
+ {"",ERROR},
+#line 143 "TokenLookup.gperf"
+ {"descending", DESCENDING},
+#line 184 "TokenLookup.gperf"
+ {"no-preserve", NO_PRESERVE},
+#line 140 "TokenLookup.gperf"
+ {"default", DEFAULT},
+#line 176 "TokenLookup.gperf"
+ {"let", LET},
+#line 200 "TokenLookup.gperf"
+ {"schema-element", SCHEMA_ELEMENT},
+ {"",ERROR}, {"",ERROR},
+#line 137 "TokenLookup.gperf"
+ {"construction", CONSTRUCTION},
+#line 142 "TokenLookup.gperf"
+ {"descendant-or-self", DESCENDANT_OR_SELF},
+#line 202 "TokenLookup.gperf"
+ {"self", SELF},
+#line 183 "TokenLookup.gperf"
+ {"no-inherit", NO_INHERIT},
+ {"",ERROR},
+#line 158 "TokenLookup.gperf"
+ {"follows", FOLLOWS},
+#line 120 "TokenLookup.gperf"
+ {"ancestor", ANCESTOR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 209 "TokenLookup.gperf"
+ {"to", TO},
+#line 160 "TokenLookup.gperf"
+ {"function", FUNCTION},
+#line 135 "TokenLookup.gperf"
+ {"collation", COLLATION},
+ {"",ERROR},
+#line 205 "TokenLookup.gperf"
+ {"strict", STRICT},
+ {"",ERROR},
+#line 173 "TokenLookup.gperf"
+ {"lax", LAX},
+ {"",ERROR},
+#line 149 "TokenLookup.gperf"
+ {"empty", EMPTY},
+ {"",ERROR},
+#line 185 "TokenLookup.gperf"
+ {"of", OF},
+#line 195 "TokenLookup.gperf"
+ {"preserve", PRESERVE},
+#line 156 "TokenLookup.gperf"
+ {"following", FOLLOWING},
+ {"",ERROR}, {"",ERROR},
+#line 171 "TokenLookup.gperf"
+ {"is", IS},
+#line 192 "TokenLookup.gperf"
+ {"precedes", PRECEDES},
+#line 150 "TokenLookup.gperf"
+ {"empty-sequence", EMPTY_SEQUENCE},
+ {"",ERROR}, {"",ERROR},
+#line 157 "TokenLookup.gperf"
+ {"following-sibling", FOLLOWING_SIBLING},
+#line 169 "TokenLookup.gperf"
+ {"instance", INSTANCE},
+#line 213 "TokenLookup.gperf"
+ {"unordered", UNORDERED},
+#line 128 "TokenLookup.gperf"
+ {"base-uri", BASEURI},
+#line 197 "TokenLookup.gperf"
+ {"return", RETURN},
+ {"",ERROR},
+#line 214 "TokenLookup.gperf"
+ {"validate", VALIDATE},
+ {"",ERROR},
+#line 138 "TokenLookup.gperf"
+ {"copy-namespaces", COPY_NAMESPACES},
+#line 186 "TokenLookup.gperf"
+ {"option", OPTION},
+#line 165 "TokenLookup.gperf"
+ {"if", IF},
+ {"",ERROR},
+#line 193 "TokenLookup.gperf"
+ {"preceding", PRECEDING},
+ {"",ERROR}, {"",ERROR},
+#line 168 "TokenLookup.gperf"
+ {"in", IN},
+ {"",ERROR},
+#line 170 "TokenLookup.gperf"
+ {"intersect", INTERSECT},
+#line 212 "TokenLookup.gperf"
+ {"union", UNION},
+ {"",ERROR},
+#line 194 "TokenLookup.gperf"
+ {"preceding-sibling", PRECEDING_SIBLING},
+#line 188 "TokenLookup.gperf"
+ {"ordering", ORDERING},
+#line 203 "TokenLookup.gperf"
+ {"some", SOME},
+#line 134 "TokenLookup.gperf"
+ {"child", CHILD},
+ {"",ERROR},
+#line 187 "TokenLookup.gperf"
+ {"ordered", ORDERED},
+#line 215 "TokenLookup.gperf"
+ {"variable", VARIABLE},
+ {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 190 "TokenLookup.gperf"
+ {"or", OR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 136 "TokenLookup.gperf"
+ {"comment", COMMENT},
+ {"",ERROR}, {"",ERROR},
+#line 211 "TokenLookup.gperf"
+ {"typeswitch", TYPESWITCH},
+ {"",ERROR},
+#line 167 "TokenLookup.gperf"
+ {"inherit", INHERIT},
+#line 144 "TokenLookup.gperf"
+ {"div", DIV},
+ {"",ERROR}, {"",ERROR},
+#line 179 "TokenLookup.gperf"
+ {"module", MODULE},
+ {"",ERROR},
+#line 159 "TokenLookup.gperf"
+ {"for", FOR},
+#line 180 "TokenLookup.gperf"
+ {"namespace", NAMESPACE},
+ {"",ERROR}, {"",ERROR},
+#line 216 "TokenLookup.gperf"
+ {"version", VERSION},
+ {"",ERROR}, {"",ERROR},
+#line 206 "TokenLookup.gperf"
+ {"strip", STRIP},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 189 "TokenLookup.gperf"
+ {"order", ORDER},
+#line 191 "TokenLookup.gperf"
+ {"parent", PARENT},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 178 "TokenLookup.gperf"
+ {"mod", MOD},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR},
+#line 166 "TokenLookup.gperf"
+ {"import", IMPORT},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 196 "TokenLookup.gperf"
+ {"processing-instruction", PROCESSING_INSTRUCTION},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 172 "TokenLookup.gperf"
+ {"item", ITEM},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR},
+#line 164 "TokenLookup.gperf"
+ {"idiv", IDIV}
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = hash (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ {
+ register const char *s = wordlist[key].name;
+
+ if (*str == *s && !strcmp (str + 1, s + 1))
+ return &wordlist[key];
+ }
+ }
+ return 0;
+}
+#line 219 "TokenLookup.gperf"
+
+
+} /* Close the QPatternist namespace. */
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/qtokenrevealer.cpp b/src/xmlpatterns/parser/qtokenrevealer.cpp
new file mode 100644
index 0000000..8e10204
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenrevealer.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtokenrevealer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TokenRevealer::TokenRevealer(const QUrl &uri,
+ const Tokenizer::Ptr &other) : Tokenizer(uri)
+ , m_tokenizer(other)
+{
+ Q_ASSERT(other);
+}
+
+TokenRevealer::~TokenRevealer()
+{
+ qDebug() << "Tokens Revealed:" << m_result;
+}
+
+void TokenRevealer::setParserContext(const ParserContext::Ptr &parseInfo)
+{
+ m_tokenizer->setParserContext(parseInfo);
+}
+
+Tokenizer::Token TokenRevealer::nextToken(YYLTYPE *const sourceLocator)
+{
+ const Token token(m_tokenizer->nextToken(sourceLocator));
+ const QString asString(tokenToString(token));
+ const TokenType type = token.type;
+
+ /* Indent. */
+ switch(type)
+ {
+ case CURLY_LBRACE:
+ {
+ m_result += QLatin1Char('\n') + m_indentationString + asString + QLatin1Char('\n');
+ m_indentationString.append(QLatin1String(" "));
+ m_result += m_indentationString;
+ break;
+ }
+ case CURLY_RBRACE:
+ {
+ m_indentationString.chop(4);
+ m_result += QLatin1Char('\n') + m_indentationString + asString;
+ break;
+ }
+ case SEMI_COLON:
+ /* Fallthrough. */
+ case COMMA:
+ {
+ m_result += asString + QLatin1Char('\n') + m_indentationString;
+ break;
+ }
+ default:
+ m_result += asString + QLatin1Char(' ');
+ }
+
+ return token;
+}
+
+int TokenRevealer::commenceScanOnly()
+{
+ return m_tokenizer->commenceScanOnly();
+}
+
+void TokenRevealer::resumeTokenizationFrom(const int position)
+{
+ m_tokenizer->resumeTokenizationFrom(position);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/qtokenrevealer_p.h b/src/xmlpatterns/parser/qtokenrevealer_p.h
new file mode 100644
index 0000000..8b6ef96
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenrevealer_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TokenRevealer_h
+#define Patternist_TokenRevealer_h
+
+#include <QSet>
+
+#include "qtokenizer_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Delegates another Tokenizer, and while doing so
+ * prints the tokens it delivers to @c stderr.
+ *
+ * Hence, this class is used solely for debugging.
+ *
+ * @since 4.5
+ */
+ class TokenRevealer : public Tokenizer
+ {
+ public:
+ TokenRevealer(const QUrl &uri,
+ const Tokenizer::Ptr &other);
+
+ virtual ~TokenRevealer();
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator);
+ virtual int commenceScanOnly();
+ virtual void resumeTokenizationFrom(const int position);
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo);
+
+ private:
+ const Tokenizer::Ptr m_tokenizer;
+ QString m_result;
+ QString m_indentationString;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/parser/qtokensource.cpp b/src/xmlpatterns/parser/qtokensource.cpp
new file mode 100644
index 0000000..99ad910
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokensource.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtokensource_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TokenSource::~TokenSource()
+{
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/parser/qtokensource_p.h b/src/xmlpatterns/parser/qtokensource_p.h
new file mode 100644
index 0000000..0ffb916
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokensource_p.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TokenSource_H
+#define Patternist_TokenSource_H
+
+#include "qatomiccomparator_p.h"
+#include "qatomicmathematician_p.h"
+#include "qcombinenodes_p.h"
+#include "qfunctionargument_p.h"
+#include "qitem_p.h"
+#include "qitemtype_p.h"
+#include "qorderby_p.h"
+#include "qpath_p.h"
+#include "qquerytransformparser_p.h"
+#include "qvalidate_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QQueue;
+
+namespace QPatternist
+{
+ /**
+ * @short A union of all the enums the parser uses.
+ */
+ union EnumUnion
+ {
+ AtomicComparator::Operator valueOperator;
+ AtomicMathematician::Operator mathOperator;
+ CombineNodes::Operator combinedNodeOp;
+ QXmlNodeModelIndex::Axis axis;
+ QXmlNodeModelIndex::DocumentOrder nodeOperator;
+ StaticContext::BoundarySpacePolicy boundarySpacePolicy;
+ StaticContext::ConstructionMode constructionMode;
+ StaticContext::OrderingEmptySequence orderingEmptySequence;
+ StaticContext::OrderingMode orderingMode;
+ OrderBy::OrderSpec::Direction sortDirection;
+ Validate::Mode validationMode;
+ VariableSlotID slot;
+ int tokenizerPosition;
+ qint16 zeroer;
+ bool Bool;
+ xsDouble Double;
+ Path::Kind pathKind;
+ };
+
+ /**
+ * @short Base class for components that needs to return tokens.
+ *
+ * TokenSource represents a stream of Token instances. The end
+ * is reached when readNext() returns a Token constructed with
+ * END_OF_FILE.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a
+ * Tokenizer for XPath or XQuery</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class TokenSource : public QSharedData
+ {
+ public:
+ /**
+ * typedef for the enum Bison generates that contains
+ * the token symbols.
+ */
+ typedef yytokentype TokenType;
+
+ /**
+ * Represents a token by carrying its name and value.
+ */
+ class Token
+ {
+ public:
+ /**
+ * Constructs an invalid Token. This default constructor
+ * is need in Qt's container classes.
+ */
+ inline Token() {}
+ inline Token(const TokenType t) : type(t) {}
+ inline Token(const TokenType t, const QString &val) : type(t), value(val) {}
+
+ bool hasError() const
+ {
+ return type == ERROR;
+ }
+
+ TokenType type;
+ QString value;
+ };
+
+ typedef QExplicitlySharedDataPointer<TokenSource> Ptr;
+ typedef QQueue<Ptr> Queue;
+
+ /**
+ * The C++ compiler cannot synthesize it when we use the
+ * Q_DISABLE_COPY() macro.
+ */
+ inline TokenSource()
+ {
+ }
+
+ virtual ~TokenSource();
+
+ /**
+ * @returns the next token.
+ */
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator) = 0;
+
+ private:
+ Q_DISABLE_COPY(TokenSource)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/querytransformparser.ypp b/src/xmlpatterns/parser/querytransformparser.ypp
new file mode 100644
index 0000000..186538c
--- /dev/null
+++ b/src/xmlpatterns/parser/querytransformparser.ypp
@@ -0,0 +1,4680 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
+%{
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
+#include <limits>
+
+#include <QUrl>
+
+#include "qabstractfloat_p.h"
+#include "qandexpression_p.h"
+#include "qanyuri_p.h"
+#include "qapplytemplate_p.h"
+#include "qargumentreference_p.h"
+#include "qarithmeticexpression_p.h"
+#include "qatomicstring_p.h"
+#include "qattributeconstructor_p.h"
+#include "qattributenamevalidator_p.h"
+#include "qaxisstep_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcalltemplate_p.h"
+#include "qcastableas_p.h"
+#include "qcastas_p.h"
+#include "qcombinenodes_p.h"
+#include "qcommentconstructor_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qcomputednamespaceconstructor_p.h"
+#include "qcontextitem_p.h"
+#include "qcopyof_p.h"
+#include "qcurrentitemstore_p.h"
+#include "qdebug_p.h"
+#include "qdelegatingnamespaceresolver_p.h"
+#include "qdocumentconstructor_p.h"
+#include "qelementconstructor_p.h"
+#include "qemptysequence_p.h"
+#include "qemptysequencetype_p.h"
+#include "qevaluationcache_p.h"
+#include "qexpressionfactory_p.h"
+#include "qexpressionsequence_p.h"
+#include "qexpressionvariablereference_p.h"
+#include "qexternalvariablereference_p.h"
+#include "qforclause_p.h"
+#include "qfunctioncall_p.h"
+#include "qfunctionfactory_p.h"
+#include "qfunctionsignature_p.h"
+#include "qgeneralcomparison_p.h"
+#include "qgenericpredicate_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qifthenclause_p.h"
+#include "qinstanceof_p.h"
+#include "qletclause_p.h"
+#include "qliteral_p.h"
+#include "qlocalnametest_p.h"
+#include "qnamespaceconstructor_p.h"
+#include "qnamespacenametest_p.h"
+#include "qncnameconstructor_p.h"
+#include "qnodecomparison_p.h"
+#include "qnodesort_p.h"
+#include "qorderby_p.h"
+#include "qorexpression_p.h"
+#include "qparsercontext_p.h"
+#include "qpath_p.h"
+#include "qpatternistlocale_p.h"
+#include "qpositionalvariablereference_p.h"
+#include "qprocessinginstructionconstructor_p.h"
+#include "qqnameconstructor_p.h"
+#include "qqnametest_p.h"
+#include "qqnamevalue_p.h"
+#include "qquantifiedexpression_p.h"
+#include "qrangeexpression_p.h"
+#include "qrangevariablereference_p.h"
+#include "qreturnorderby_p.h"
+#include "qschemanumeric_p.h"
+#include "qschematypefactory_p.h"
+#include "qsimplecontentconstructor_p.h"
+#include "qstaticbaseuristore_p.h"
+#include "qstaticcompatibilitystore_p.h"
+#include "qtemplateparameterreference_p.h"
+#include "qtemplate_p.h"
+#include "qtextnodeconstructor_p.h"
+#include "qtokenizer_p.h"
+#include "qtreatas_p.h"
+#include "qtypechecker_p.h"
+#include "qunaryexpression_p.h"
+#include "qunresolvedvariablereference_p.h"
+#include "quserfunctioncallsite_p.h"
+#include "qvaluecomparison_p.h"
+#include "qxpathhelper_p.h"
+#include "qxsltsimplecontentconstructor_p.h"
+
+/*
+ * The cpp generated with bison 2.1 wants to
+ * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
+ */
+#define YYMALLOC malloc
+#define YYFREE free
+
+QT_BEGIN_NAMESPACE
+
+/* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
+ * undocumented reason. */
+namespace QPatternist
+{
+
+/**
+ * "Macro that you define with #define in the Bison declarations
+ * section to request verbose, specific error message strings when
+ * yyerror is called."
+ */
+#define YYERROR_VERBOSE 1
+
+#undef YYLTYPE_IS_TRIVIAL
+#define YYLTYPE_IS_TRIVIAL 0
+
+/* Suppresses `warning: "YYENABLE_NLS" is not defined`
+ * @c YYENABLE_NLS enables Bison internationalization, and we don't
+ * use that, so disable it. See the Bison Manual, section 4.5 Parser Internationalization.
+ */
+#define YYENABLE_NLS 0
+
+static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return QSourceLocation(parseInfo->tokenizer->queryURI(),
+ sourceLocator.first_line,
+ sourceLocator.first_column);
+}
+
+/**
+ * @internal
+ * @relates QXmlQuery
+ */
+typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;
+
+/**
+ * @short Flags invalid expressions and declarations in the currently
+ * parsed language.
+ *
+ * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and
+ * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's
+ * identity constraints, it is the union of all the constructs in these
+ * languages. However, when dealing with each language individually, we
+ * regularly need to disallow some expressions, such as direct element
+ * constructors when parsing XSL-T, or the typeswitch when parsing XPath.
+ *
+ * This is further complicated by that XSLTTokenizer sometimes generates code
+ * which is allowed in XQuery but not in XPath. For that reason the token
+ * INTERNAL is sometimes generated, which signals that an expression, for
+ * instance the @c let clause, should not be flagged as an error, because it's
+ * used for internal purposes.
+ *
+ * Hence, this function is called from each expression and declaration with @p
+ * allowedLanguages stating what languages it is allowed in.
+ *
+ * If @p isInternal is @c true, no error is raised. Otherwise, if the current
+ * language is not in @p allowedLanguages, an error is raised.
+ */
+static void allowedIn(const QueryLanguages allowedLanguages,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const bool isInternal = false)
+{
+ /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed
+ * and XSL-T is the language, it's ok. */
+ if(!isInternal &&
+ (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
+ {
+
+ QString langName;
+
+ switch(parseInfo->languageAccent)
+ {
+ case QXmlQuery::XPath20:
+ langName = QLatin1String("XPath 2.0");
+ break;
+ case QXmlQuery::XSLT20:
+ langName = QLatin1String("XSL-T 2.0");
+ break;
+ case QXmlQuery::XQuery10:
+ langName = QLatin1String("XQuery 1.0");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintSelector:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintField:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
+ break;
+ }
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered "
+ "which is disallowed in the current language(%1).").arg(langName),
+ ReportContext::XPST0003,
+ fromYYLTYPE(sourceLocator, parseInfo));
+
+ }
+}
+
+static inline bool isVariableReference(const Expression::ID id)
+{
+ return id == Expression::IDExpressionVariableReference
+ || id == Expression::IDRangeVariableReference
+ || id == Expression::IDArgumentReference;
+}
+
+class ReflectYYLTYPE : public SourceLocationReflection
+{
+public:
+ inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const pi) : m_sl(sourceLocator)
+ , m_parseInfo(pi)
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const
+ {
+ return this;
+ }
+
+ virtual QSourceLocation sourceLocation() const
+ {
+ return fromYYLTYPE(m_sl, m_parseInfo);
+ }
+
+ virtual QString description() const
+ {
+ Q_ASSERT(false);
+ return QString();
+ }
+
+private:
+ const YYLTYPE &m_sl;
+ const ParserContext *const m_parseInfo;
+};
+
+/**
+ * @short Centralizes a translation string for the purpose of increasing consistency.
+ */
+static inline QString unknownType()
+{
+ return QtXmlPatterns::tr("%1 is an unknown schema type.");
+}
+
+static inline Expression::Ptr create(Expression *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Expression::Ptr(expr);
+}
+
+static inline Template::Ptr create(Template *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Template::Ptr(expr);
+}
+
+static inline Expression::Ptr create(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
+ return expr;
+}
+
+static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
+ sourceLocator,
+ parseInfo);
+}
+
+static void loadPattern(const Expression::Ptr &matchPattern,
+ TemplatePattern::Vector &ourPatterns,
+ const TemplatePattern::ID id,
+ const PatternPriority priority,
+ const Template::Ptr &temp)
+{
+ Q_ASSERT(temp);
+
+ const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;
+
+ ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
+}
+
+static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
+ const SequenceType::Ptr &reqType,
+ const ParserContext *const parseInfo)
+{
+ return TypeChecker::applyFunctionConversion(body, reqType,
+ parseInfo->staticContext,
+ ReportContext::XTTE0505,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert | TypeChecker::GeneratePromotion));
+}
+
+static void registerNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &body,
+ ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const Template::Ptr &temp)
+{
+ Template::Ptr &e = parseInfo->namedTemplates[name];
+
+ if(e)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A template by name %1 "
+ "has already been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(),
+ name)),
+ ReportContext::XTSE0660,
+ fromYYLTYPE(sourceLocator, parseInfo));
+ }
+ else
+ {
+ e = temp;
+ e->body = body;
+ }
+}
+
+/**
+ * @short Centralizes code for creating numeric literals.
+ */
+template<typename TNumberClass>
+Expression::Ptr createNumericLiteral(const QString &in,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Item num(TNumberClass::fromLexical(in));
+
+ if(num.template as<AtomicValue>()->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid numeric literal.")
+ .arg(formatData(in)),
+ ReportContext::XPST0003, fromYYLTYPE(sl, parseInfo));
+ return Expression::Ptr(); /* Avoid compiler warning. */
+ }
+ else
+ return create(new Literal(num), sl, parseInfo);
+}
+
+/**
+ * @short The generated Bison parser calls this function when there is a parse error.
+ *
+ * It is not called, nor should be, for logical errors(which the Bison not know about). For those,
+ * ReportContext::error() is called.
+ */
+static int XPatherror(YYLTYPE *sourceLocator, const ParserContext *const parseInfo, const char *const msg)
+{
+ Q_UNUSED(sourceLocator);
+ Q_ASSERT(parseInfo);
+
+ parseInfo->staticContext->error(escape(QLatin1String(msg)), ReportContext::XPST0003, fromYYLTYPE(*sourceLocator, parseInfo));
+ return 1;
+}
+
+/**
+ * When we want to connect the OrderBy and ReturnOrderBy, it might be that we have other expressions, such
+ * as @c where and @c let inbetween. We need to continue through them. This function does that.
+ */
+static ReturnOrderBy *locateReturnClause(const Expression::Ptr &expr)
+{
+ Q_ASSERT(expr);
+
+ const Expression::ID id = expr->id();
+ if(id == Expression::IDLetClause || id == Expression::IDIfThenClause || id == Expression::IDForClause)
+ return locateReturnClause(expr->operands()[1]);
+ else if(id == Expression::IDReturnOrderBy)
+ return expr->as<ReturnOrderBy>();
+ else
+ return 0;
+}
+
+static inline bool isPredicate(const Expression::ID id)
+{
+ return id == Expression::IDGenericPredicate ||
+ id == Expression::IDFirstItemPredicate;
+}
+
+/**
+ * Assumes expr is an AxisStep wrapped in some kind of predicates or paths. Filters
+ * through the predicates and returns the AxisStep.
+ */
+static Expression::Ptr findAxisStep(const Expression::Ptr &expr,
+ const bool throughStructures = true)
+{
+ Q_ASSERT(expr);
+
+ if(!throughStructures)
+ return expr;
+
+ Expression *candidate = expr.data();
+ Expression::ID id = candidate->id();
+
+ while(isPredicate(id) || id == Expression::IDPath)
+ {
+ const Expression::List &children = candidate->operands();
+ if(children.isEmpty())
+ return Expression::Ptr();
+ else
+ {
+ candidate = children.first().data();
+ id = candidate->id();
+ }
+ }
+
+ if(id == Expression::IDEmptySequence)
+ return Expression::Ptr();
+ else
+ {
+ Q_ASSERT(candidate->is(Expression::IDAxisStep));
+ return Expression::Ptr(candidate);
+ }
+}
+
+static void changeToTopAxis(const Expression::Ptr &op)
+{
+ /* This axis must have been written away by now. */
+ Q_ASSERT(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisChild);
+
+ if(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisSelf)
+ op->as<AxisStep>()->setAxis(QXmlNodeModelIndex::AxisAttributeOrTop);
+}
+
+/**
+ * @short Writes @p operand1 and @p operand2, two operands in an XSL-T pattern,
+ * into an equivalent XPath expression.
+ *
+ * Essentially, the following rewrite is done:
+ *
+ * <tt>
+ * axis1::test1(a)/axis2::test2(b)
+ * =>
+ * child-or-top::test2(b)[parent::test1(a)]
+ * </tt>
+ *
+ * Section 5.5.3 The Meaning of a Pattern talks about rewrites that are applied to
+ * only the first step in a pattern, but since we're doing rewrites more radically,
+ * its line of reasoning cannot be followed.
+ *
+ * Keep in mind the rewrites that non-terminal PatternStep do.
+ *
+ * @see createIdPatternPath()
+ */
+static inline Expression::Ptr createPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandL(findAxisStep(operand1, false));
+
+ if(operandL->is(Expression::IDAxisStep))
+ operandL->as<AxisStep>()->setAxis(axis);
+ else
+ findAxisStep(operand1)->as<AxisStep>()->setAxis(axis);
+
+ return create(GenericPredicate::create(operand2, operandL,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Performs the same role as createPatternPath(), but is tailored
+ * for @c fn:key() and @c fn:id().
+ *
+ * @c fn:key() and @c fn:id() can be part of path patterns(only as the first step,
+ * to be precise) and that poses a challenge to rewriting because what
+ * createPatternPath() is not possible to express, since the functions cannot be
+ * node tests. E.g, this rewrite is not possible:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::id-or-key]
+ * </tt>
+ *
+ * Our approach is to rewrite like this:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::node is id-or-key]
+ * </tt>
+ *
+ * @p operand1 is the call to @c fn:key() or @c fn:id(), @p operand2
+ * the right operand, and @p axis the target axis to rewrite to.
+ *
+ * @see createPatternPath()
+ */
+static inline Expression::Ptr createIdPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandR(findAxisStep(operand2));
+ Q_ASSERT(operandR);
+ changeToTopAxis(operandR);
+
+ const Expression::Ptr parentStep(create(new AxisStep(axis, BuiltinTypes::node),
+ sl,
+ parseInfo));
+ const Expression::Ptr isComp(create(new NodeComparison(parentStep,
+ QXmlNodeModelIndex::Is,
+ operand1),
+ sl,
+ parseInfo));
+
+ return create(GenericPredicate::create(operandR, isComp,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Centralizes a translation message, for the
+ * purpose of consistency and modularization.
+ */
+static inline QString prologMessage(const char *const msg)
+{
+ Q_ASSERT(msg);
+ return QtXmlPatterns::tr("Only one %1 declaration can occur in the query prolog.").arg(formatKeyword(msg));
+}
+
+/**
+ * @short Resolves against the static base URI and checks that @p collation
+ * is a supported Unicode Collation.
+ *
+ * "If a default collation declaration specifies a collation by a
+ * relative URI, that relative URI is resolved to an absolute
+ * URI using the base URI in the static context."
+ *
+ * @returns the Unicode Collation properly resolved, if @p collation is a valid collation
+ */
+template<const ReportContext::ErrorCode errorCode>
+static QUrl resolveAndCheckCollation(const QString &collation,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ QUrl uri(AnyURI::toQUrl<ReportContext::XQST0046>(collation, parseInfo->staticContext, &ryy));
+
+ if(uri.isRelative())
+ uri = parseInfo->staticContext->baseURI().resolved(uri);
+
+ XPathHelper::checkCollationSupport<errorCode>(uri.toString(), parseInfo->staticContext, &ryy);
+
+ return uri;
+}
+
+/* The Bison generated parser declares macros that aren't used
+ * so suppress the warnings by fake usage of them.
+ *
+ * We do the same for some more defines in the first action. */
+#if defined(YYLSP_NEEDED) \
+ || defined(YYBISON) \
+ || defined(YYBISON_VERSION) \
+ || defined(YYPURE) \
+ || defined(yydebug) \
+ || defined(YYSKELETON_NAME)
+#endif
+
+/**
+ * Wraps @p operand with a CopyOf in case it makes any difference.
+ *
+ * There is no need to wrap the return value in a call to create(), it's
+ * already done.
+ */
+static Expression::Ptr createCopyOf(const Expression::Ptr &operand,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ return create(new CopyOf(operand, parseInfo->inheritNamespacesMode,
+ parseInfo->preserveNamespacesMode), sl, parseInfo);
+}
+
+static Expression::Ptr createCompatStore(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(new StaticCompatibilityStore(expr), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates an Expression that corresponds to <tt>/</tt>. This is literally
+ * <tt>fn:root(self::node()) treat as document-node()</tt>.
+ */
+static Expression::Ptr createRootExpression(const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::root);
+
+ Expression::List args;
+ args.append(create(new ContextItem(), sl, parseInfo));
+
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ const Expression::Ptr fnRoot(parseInfo->staticContext->functionSignatures()
+ ->createFunctionCall(name, args, parseInfo->staticContext, &ryy));
+ Q_ASSERT(fnRoot);
+
+ return create(new TreatAs(create(fnRoot, sl, parseInfo), CommonSequenceTypes::ExactlyOneDocumentNode), sl, parseInfo);
+}
+
+static int XPathlex(YYSTYPE *lexVal, YYLTYPE *sourceLocator, const ParserContext *const parseInfo)
+{
+#ifdef Patternist_DEBUG_PARSER
+ /**
+ * "External integer variable set to zero by default. If yydebug
+ * is given a nonzero value, the parser will output information on
+ * input symbols and parser action. See section Debugging Your Parser."
+ */
+# define YYDEBUG 1
+
+ extern int XPathdebug;
+ XPathdebug = 1;
+#endif
+
+ Q_ASSERT(parseInfo);
+
+ const Tokenizer::Token tok(parseInfo->tokenizer->nextToken(sourceLocator));
+
+ (*lexVal).sval = tok.value;
+
+ return static_cast<int>(tok.type);
+}
+
+/**
+ * @short Creates a path expression which contains the step <tt>//</tt> between
+ * @p begin and and @p end.
+ *
+ * <tt>begin//end</tt> is a short form for: <tt>begin/descendant-or-self::node()/end</tt>
+ *
+ * This will be compiled as two-path expression: <tt>(/)/(//.)/step/</tt>
+ */
+static Expression::Ptr createSlashSlashPath(const Expression::Ptr &begin,
+ const Expression::Ptr &end,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr twoSlash(create(new AxisStep(QXmlNodeModelIndex::AxisDescendantOrSelf, BuiltinTypes::node), sourceLocator, parseInfo));
+ const Expression::Ptr p1(create(new Path(begin, twoSlash), sourceLocator, parseInfo));
+
+ return create(new Path(p1, end), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates a call to <tt>fn:concat()</tt> with @p args as the arguments.
+ */
+static inline Expression::Ptr createConcatFN(const ParserContext *const parseInfo,
+ const Expression::List &args,
+ const YYLTYPE &sourceLocator)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::concat);
+ const ReflectYYLTYPE ryy(sourceLocator, parseInfo);
+
+ return create(parseInfo->staticContext->functionSignatures()->createFunctionCall(name, args, parseInfo->staticContext, &ryy),
+ sourceLocator, parseInfo);
+}
+
+static inline Expression::Ptr createDirAttributeValue(const Expression::List &content,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator)
+{
+ if(content.isEmpty())
+ return create(new EmptySequence(), sourceLocator, parseInfo);
+ else if(content.size() == 1)
+ return content.first();
+ else
+ return createConcatFN(parseInfo, content, sourceLocator);
+}
+
+/**
+ * @short Checks for variable initialization circularity.
+ *
+ * "A recursive function that checks for recursion is full of ironies."
+ *
+ * -- The Salsa Master
+ *
+ * Issues an error via @p parseInfo's StaticContext if the initialization
+ * expression @p checkee for the global variable @p var, contains a variable
+ * reference to @p var. That is, if there's a circularity.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#ERRXQST0054">XQuery 1.0: An XML
+ * Query Language, err:XQST0054</a>
+ */
+static void checkVariableCircularity(const VariableDeclaration::Ptr &var,
+ const Expression::Ptr &checkee,
+ const VariableDeclaration::Type type,
+ FunctionSignature::List &signList,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(var);
+ Q_ASSERT(checkee);
+ Q_ASSERT(parseInfo);
+
+ const Expression::ID id = checkee->id();
+
+ if(id == Expression::IDExpressionVariableReference)
+ {
+ const ExpressionVariableReference *const ref =
+ static_cast<const ExpressionVariableReference *>(checkee.data());
+
+ if(var->slot == ref->slot() && type == ref->variableDeclaration()->type)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The initialization of variable %1 "
+ "depends on itself").arg(formatKeyword(var, parseInfo->staticContext->namePool())),
+ parseInfo->isXSLT() ? ReportContext::XTDE0640 : ReportContext::XQST0054, ref);
+ return;
+ }
+ else
+ {
+ /* If the variable we're checking is below another variable, it can be a recursive
+ * dependency through functions, so we need to check variable references too. */
+ checkVariableCircularity(var, ref->sourceExpression(), type, signList, parseInfo);
+ return;
+ }
+ }
+ else if(id == Expression::IDUserFunctionCallsite)
+ {
+ const UserFunctionCallsite::Ptr callsite(checkee);
+ const FunctionSignature::Ptr sign(callsite->callTargetDescription());
+ const FunctionSignature::List::const_iterator end(signList.constEnd());
+ FunctionSignature::List::const_iterator it(signList.constBegin());
+ bool noMatch = true;
+
+ for(; it != end; ++it)
+ {
+ if(*it == sign)
+ {
+ /* The variable we're checking is depending on a function that's recursive. The
+ * user has written a weird query, in other words. Since it's the second time
+ * we've encountered a callsite, we now skip it. */
+ noMatch = false;
+ break;
+ }
+ }
+
+ if(noMatch)
+ {
+ signList.append(sign);
+ /* Check the body of the function being called. */
+ checkVariableCircularity(var, callsite->body(), type, signList, parseInfo);
+ }
+ /* Continue with the operands, such that we also check the arguments of the callsite. */
+ }
+ else if(id == Expression::IDUnresolvedVariableReference)
+ {
+ /* We're called before it has rewritten itself. */
+ checkVariableCircularity(var, checkee->as<UnresolvedVariableReference>()->replacement(), type, signList, parseInfo);
+ }
+
+ /* Check the operands. */
+ const Expression::List ops(checkee->operands());
+ if(ops.isEmpty())
+ return;
+
+ const Expression::List::const_iterator end(ops.constEnd());
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ checkVariableCircularity(var, *it, type, signList, parseInfo);
+}
+
+static void variableUnavailable(const QXmlName &variableName,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &location)
+{
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No variable with name %1 exists")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), variableName)),
+ ReportContext::XPST0008, fromYYLTYPE(location, parseInfo));
+}
+
+/**
+ * The Cardinality in a TypeDeclaration for a variable in a quantification has no effect,
+ * and this function ensures this by changing @p type to Cardinality Cardinality::zeroOrMore().
+ *
+ * @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=3305">Bugzilla Bug 3305
+ * Cardinality + on range variables</a>
+ * @see ParserContext::finalizePushedVariable()
+ */
+static inline SequenceType::Ptr quantificationType(const SequenceType::Ptr &type)
+{
+ Q_ASSERT(type);
+ return makeGenericSequenceType(type->itemType(), Cardinality::zeroOrMore());
+}
+
+/**
+ * @p seqType and @p expr may be @c null.
+ */
+static Expression::Ptr pushVariable(const QXmlName name,
+ const SequenceType::Ptr &seqType,
+ const Expression::Ptr &expr,
+ const VariableDeclaration::Type type,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool checkSource = true)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* -2 will cause Q_ASSERTs to trigger if it isn't changed. */
+ VariableSlotID slot = -2;
+
+ switch(type)
+ {
+ case VariableDeclaration::FunctionArgument:
+ /* Fallthrough. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ slot = parseInfo->allocateExpressionSlot();
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ {
+ slot = parseInfo->allocateGlobalVariableSlot();
+ break;
+ }
+ case VariableDeclaration::RangeVariable:
+ {
+ slot = parseInfo->staticContext->allocateRangeSlot();
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ slot = parseInfo->allocatePositionalSlot();
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ /* Fallthrough. We do nothing, template parameters
+ * doesn't use context slots at all, they're hashed
+ * on the name. */
+ case VariableDeclaration::ExternalVariable:
+ /* We do nothing, external variables doesn't use
+ *context slots/stack frames at all. */
+ ;
+ }
+
+ const VariableDeclaration::Ptr var(new VariableDeclaration(name, slot, type, seqType));
+
+ Expression::Ptr checked;
+
+ if(checkSource && seqType)
+ {
+ if(expr)
+ {
+ /* We only want to add conversion for function arguments, and variables
+ * if we're XSL-T.
+ *
+ * We unconditionally skip TypeChecker::CheckFocus because the StaticContext we
+ * pass hasn't set up the focus yet, since that's the parent's responsibility. */
+ const TypeChecker::Options options(( type == VariableDeclaration::FunctionArgument
+ || type == VariableDeclaration::TemplateParameter
+ || parseInfo->isXSLT())
+ ? TypeChecker::AutomaticallyConvert : TypeChecker::Options());
+
+ checked = TypeChecker::applyFunctionConversion(expr, seqType, parseInfo->staticContext,
+ parseInfo->isXSLT() ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ options);
+ }
+ }
+ else
+ checked = expr;
+
+ /* Add an evaluation cache for all expression variables. No EvaluationCache is needed for
+ * positional variables because in the end they are calls to Iterator::position(). Similarly,
+ * no need to cache range variables either because they are calls to DynamicContext::rangeVariable().
+ *
+ * We don't do it for function arguments because the Expression being cached depends -- it depends
+ * on the callsite. UserFunctionCallsite is responsible for the evaluation caches in that case.
+ *
+ * In some cases the EvaluationCache instance isn't necessary, but in those cases EvaluationCache
+ * optimizes itself away. */
+ if(type == VariableDeclaration::ExpressionVariable)
+ checked = create(new EvaluationCache<false>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+ else if(type == VariableDeclaration::GlobalVariable)
+ checked = create(new EvaluationCache<true>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+
+ var->setExpression(checked);
+
+ parseInfo->variables.push(var);
+ return checked;
+}
+
+static inline VariableDeclaration::Ptr variableByName(const QXmlName name,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* We walk the list backwards. */
+ const VariableDeclaration::Stack::const_iterator start(parseInfo->variables.constBegin());
+ VariableDeclaration::Stack::const_iterator it(parseInfo->variables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ Q_ASSERT(*it);
+ if((*it)->name == name)
+ return *it;
+ }
+
+ return VariableDeclaration::Ptr();
+}
+
+static Expression::Ptr resolveVariable(const QXmlName &name,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool raiseErrorOnUnavailability)
+{
+ const VariableDeclaration::Ptr var(variableByName(name, parseInfo));
+ Expression::Ptr retval;
+
+ if(var && var->type != VariableDeclaration::ExternalVariable)
+ {
+ switch(var->type)
+ {
+ case VariableDeclaration::RangeVariable:
+ {
+ retval = create(new RangeVariableReference(var->expression(), var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ /* Fallthrough. From the perspective of an ExpressionVariableReference, it can't tell
+ * a difference between a global and a local expression variable. However, the cache
+ * mechanism must. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ retval = create(new ExpressionVariableReference(var->slot, var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::FunctionArgument:
+ {
+ retval = create(new ArgumentReference(var->sequenceType, var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ retval = create(new PositionalVariableReference(var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ {
+ retval = create(new TemplateParameterReference(var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::ExternalVariable:
+ /* This code path will never be hit, but the case
+ * label silences a warning. See above. */
+ ;
+ }
+ Q_ASSERT(retval);
+ var->references.append(retval);
+ }
+ else
+ {
+ /* Let's see if your external variable loader can provide us with one. */
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable(name, CommonSequenceTypes::ZeroOrMoreItems));
+
+ if(varType)
+ {
+ const Expression::Ptr extRef(create(new ExternalVariableReference(name, varType), sourceLocator, parseInfo));
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion(extRef, varType, parseInfo->staticContext));
+ retval = checked;
+ }
+ else if(!raiseErrorOnUnavailability && parseInfo->isXSLT())
+ {
+ /* In XSL-T, global variables are in scope for the whole
+ * stylesheet, so we must resolve this first at the end. */
+ retval = create(new UnresolvedVariableReference(name), sourceLocator, parseInfo);
+ parseInfo->unresolvedVariableReferences.insert(name, retval);
+ }
+ else
+ variableUnavailable(name, parseInfo, sourceLocator);
+ }
+
+ return retval;
+}
+
+static Expression::Ptr createReturnOrderBy(const OrderSpecTransfer::List &orderSpecTransfer,
+ const Expression::Ptr &returnExpr,
+ const OrderBy::Stability stability,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ // TODO do resize(orderSpec.size() + 1)
+ Expression::List exprs;
+ OrderBy::OrderSpec::Vector orderSpecs;
+
+ exprs.append(returnExpr);
+
+ const int len = orderSpecTransfer.size();
+
+ for(int i = 0; i < len; ++i)
+ {
+ exprs.append(orderSpecTransfer.at(i).expression);
+ orderSpecs.append(orderSpecTransfer.at(i).orderSpec);
+ }
+
+ return create(new ReturnOrderBy(stability, orderSpecs, exprs), sourceLocator, parseInfo);
+}
+
+%}
+
+/* This grammar shouldn't be compiled with anything older than the Bison version
+ * specified below. This '%require' directive was introduced in Bison 2.2. */
+%require "2.3a"
+
+%name-prefix="XPath"
+
+/* Specifies the name of the generated parser. */
+%output="qquerytransformparser.cpp"
+
+/* Output the .output file. */
+%verbose
+
+/* Yes, we want descriptive error messages. */
+%error-verbose
+
+/* We'd like to be reentrant/thread-safe */
+%pure-parser
+
+/* We want code for line/columns to be generated. */
+%locations
+
+/* Create a header file and put declarations there. */
+%defines
+
+%parse-param {ParserContext *const parseInfo}
+%lex-param {ParserContext *const parseInfo}
+
+%expect 4
+/* Silences the following:
+
+state 327
+
+ 293 SequenceType: ItemType . OccurrenceIndicator
+
+ "+" shift, and go to state 379
+ "*" shift, and go to state 380
+ "?" shift, and go to state 381
+
+ "+" [reduce using rule 295 (OccurrenceIndicator)]
+ "*" [reduce using rule 295 (OccurrenceIndicator)]
+ $default reduce using rule 295 (OccurrenceIndicator)
+
+ OccurrenceIndicator go to state 382
+
+state 45
+
+ 200 PathExpr: "/" . RelativePathExpr
+ 203 | "/" .
+
+ [...]
+
+ "<" [reduce using rule 203 (PathExpr)]
+ "*" [reduce using rule 203 (PathExpr)]
+ $default reduce using rule 203 (PathExpr)
+*/
+
+%token <sval> STRING_LITERAL "<string literal>"
+
+/**
+ * This token is only used in element content and signals content that
+ * is not Boundary whitespace. Nevertheless, the token value can be all whitespace,
+ * but it was specified using character references or CDATA sections by the user. */
+%token <sval> NON_BOUNDARY_WS "<non-boundary text node>"
+
+/* XPath 2.0 allows quotes and apostrophes to be escaped with "" and ''; this token is
+ is used for XPath 2.0 literals such that we can flag syntax errors if running in
+ 1.0 mode. */
+%token <sval> XPATH2_STRING_LITERAL "<string literal(XPath 2.0)>"
+%token <sval> QNAME "QName"
+%token <sval> NCNAME "NCName"
+
+/* A QName as a clark name. See QXmlName::toClarkName(). */
+%token <sval> CLARK_NAME "ClarkName"
+
+/**
+ * Is "ncname:*". The token value does not include the colon and the star.
+ */
+%token <sval> ANY_LOCAL_NAME
+
+/**
+ * Is "*:ncname". The token value does not include the colon and the star.
+ */
+%token <sval> ANY_PREFIX
+
+/**
+ * An XPath 1.0 number literal. It is a string value because
+ * Numeric::fromLexical() does the tokenization.
+ */
+%token <sval> NUMBER "<number literal>"
+
+/**
+ * XPath 2.0 number literal. It includes the use of 'e'/'E'
+ */
+%token <sval> XPATH2_NUMBER "<number literal(XPath 2.0)>"
+
+%token ANCESTOR "ancestor"
+%token ANCESTOR_OR_SELF "ancestor-or-self"
+%token AND "and"
+%token APOS "'"
+%token APPLY_TEMPLATE "apply-template"
+%token AS "as"
+%token ASCENDING "ascending"
+%token ASSIGN ":="
+%token AT "at"
+%token AT_SIGN "@"
+%token ATTRIBUTE "attribute"
+%token AVT /* Synthetic token. Signals an attribute value template. */
+%token BAR "|"
+%token BASEURI "base-uri"
+%token BEGIN_END_TAG "</"
+%token BOUNDARY_SPACE "boundary-space"
+%token BY "by"
+%token CALL_TEMPLATE "call-template"
+%token CASE "case"
+%token CASTABLE "castable"
+%token CAST "cast"
+%token CHILD "child"
+%token COLLATION "collation"
+%token COLONCOLON "::"
+%token COMMA ","
+%token COMMENT "comment"
+%token COMMENT_START "<!--"
+%token CONSTRUCTION "construction"
+%token COPY_NAMESPACES "copy-namespaces"
+%token CURLY_LBRACE "{"
+%token CURLY_RBRACE "}"
+%token DECLARE "declare"
+%token DEFAULT "default"
+%token DESCENDANT "descendant"
+%token DESCENDANT_OR_SELF "descendant-or-self"
+%token DESCENDING "descending"
+%token DIV "div"
+%token DOCUMENT "document"
+%token DOCUMENT_NODE "document-node"
+%token DOLLAR "$"
+%token DOT "."
+%token DOTDOT ".."
+%token ELEMENT "element"
+%token ELSE "else"
+%token EMPTY "empty"
+%token EMPTY_SEQUENCE "empty-sequence"
+%token ENCODING "encoding"
+%token END_OF_FILE 0 "end of file"
+%token END_SORT "end_sort"
+%token EQ "eq"
+%token ERROR "unknown keyword" /* Used by the Tokenizer. We use the phrase "keyword" instead of "token" to be less pointy. */
+%token EVERY "every"
+%token EXCEPT "except"
+%token EXTERNAL "external"
+%token FOLLOWING "following"
+%token FOLLOWING_SIBLING "following-sibling"
+%token FOLLOWS ">>"
+%token FOR_APPLY_TEMPLATE "for-apply-template" /* Synthetic token, used in XSL-T. */
+%token FOR "for"
+%token FUNCTION "function"
+%token GE "ge"
+%token G_EQ "="
+%token G_GE ">="
+%token G_GT ">"
+%token G_LE "<="
+%token G_LT "<"
+%token G_NE "!="
+%token GREATEST "greatest"
+%token GT "gt"
+%token IDIV "idiv"
+%token IF "if"
+%token IMPORT "import"
+%token INHERIT "inherit"
+%token IN "in"
+%token INSTANCE "instance"
+%token INTERSECT "intersect"
+%token IS "is"
+%token ITEM "item"
+%token LAX "lax"
+%token LBRACKET "["
+%token LEAST "least"
+%token LE "le"
+%token LET "let"
+%token LPAREN "("
+%token LT "lt"
+%token MAP "map" /* Synthetic token, used in XSL-T. */
+%token MATCHES "matches"
+%token MINUS "-"
+%token MODE "mode" /* Synthetic token, used in XSL-T. */
+%token MOD "mod"
+%token MODULE "module"
+%token NAME "name"
+%token NAMESPACE "namespace"
+%token NE "ne"
+%token NODE "node"
+%token NO_INHERIT "no-inherit"
+%token NO_PRESERVE "no-preserve"
+%token OF "of"
+%token OPTION "option"
+%token ORDERED "ordered"
+%token ORDERING "ordering"
+%token ORDER "order"
+%token OR "or"
+%token PARENT "parent"
+%token PI_START "<?"
+%token PLUS "+"
+%token POSITION_SET /* Synthetic token. */
+%token PRAGMA_END "#)"
+%token PRAGMA_START "(#"
+%token PRECEDES "<<"
+%token PRECEDING "preceding"
+%token PRECEDING_SIBLING "preceding-sibling"
+%token PRESERVE "preserve"
+%token PRIORITY "priority"
+%token PROCESSING_INSTRUCTION "processing-instruction"
+%token QUESTION "?"
+%token QUICK_TAG_END "/>"
+%token QUOTE "\""
+%token RBRACKET "]"
+%token RETURN "return"
+%token RPAREN ")"
+%token SATISFIES "satisfies"
+%token SCHEMA_ATTRIBUTE "schema-attribute"
+%token SCHEMA_ELEMENT "schema-element"
+%token SCHEMA "schema"
+%token SELF "self"
+%token SEMI_COLON ";"
+%token SLASH "/"
+%token SLASHSLASH "//"
+%token SOME "some"
+%token SORT "sort" /* Synthetic token, used in XSL-T. */
+%token STABLE "stable"
+%token STAR "*"
+%token STRICT "strict"
+%token STRIP "strip"
+%token SUCCESS /* Synthetic token, used by the Tokenizer. */
+%token <sval> COMMENT_CONTENT
+%token <sval> PI_CONTENT
+%token <sval> PI_TARGET
+%token <sval> XSLT_VERSION /* Synthetic token, used in XSL-T. */
+%token TEMPLATE "template"
+%token TEXT "text"
+%token THEN "then"
+%token TO "to"
+%token TREAT "treat"
+%token TUNNEL "tunnel" /* Synthetic token, used in XSL-T. */
+%token TYPESWITCH "typeswitch"
+%token UNION "union"
+%token UNORDERED "unordered"
+%token VALIDATE "validate"
+%token VARIABLE "variable"
+%token VERSION "version"
+%token WHERE "where"
+%token XQUERY "xquery"
+%token INTERNAL "internal" /* Synthetic token, used in XSL-T. */
+%token INTERNAL_NAME "internal-name" /* Synthetic token, used in XSL-T. */
+%token CURRENT "current" /* Synthetic token, used in XSL-T. */
+
+/* Alphabetically. */
+%type <attributeHolder> Attribute
+%type <attributeHolders> DirAttributeList
+%type <cardinality> OccurrenceIndicator
+%type <enums.axis> Axis AxisToken
+%type <enums.boundarySpacePolicy> BoundarySpacePolicy
+%type <enums.combinedNodeOp> IntersectOperator
+%type <enums.constructionMode> ConstructionMode
+%type <enums.mathOperator> MultiplyOperator AdditiveOperator UnaryOperator
+%type <enums.nodeOperator> NodeOperator
+%type <enums.orderingEmptySequence> OrderingEmptySequence EmptynessModifier
+%type <enums.sortDirection> DirectionModifier
+
+%type <enums.orderingMode> OrderingMode
+%type <enums.slot> PositionalVar
+%type <enums.validationMode> ValidationMode
+%type <enums.valueOperator> ValueComparisonOperator GeneralComparisonOperator
+%type <expr> OrExpr AndExpr ComparisonExpr UnionExpr Literal
+ AdditiveExpr MultiplicativeExpr PrimaryExpr FilterExpr
+ StepExpr PathExpr RelativePathExpr Expr ExprSingle
+ VarRef ContextItemExpr IfExpr CastExpr CastableExpr
+ TreatExpr InstanceOfExpr ValueExpr UnaryExpr NodeComp
+ IntersectExceptExpr RangeExpr ParenthesizedExpr
+ ValueComp FunctionCallExpr GeneralComp ForClause
+ WhereClause FLWORExpr ForTail QuantifiedExpr QueryBody
+ SomeQuantificationExpr SomeQuantificationTail
+ EveryQuantificationExpr EveryQuantificationTail
+ ExtensionExpr EnclosedOptionalExpr VariableValue
+ EnclosedExpr FunctionBody ValidateExpr NumericLiteral
+ OrderingExpr TypeswitchExpr LetClause LetTail
+ Constructor DirectConstructor DirElemConstructor
+ ComputedConstructor CompDocConstructor CompElemConstructor
+ CompTextConstructor CompCommentConstructor CompPIConstructor
+ DirPIConstructor CompAttrConstructor DirElemConstructorTail
+ AxisStep ForwardStep ReverseStep AbbrevForwardStep
+ CaseDefault CaseClause CaseTail CompAttributeName
+ FilteredAxisStep DirCommentConstructor CompPIName
+ DirAttributeValue AbbrevReverseStep CompNamespaceConstructor
+ CompElementName CompNameExpr SatisfiesClause Pattern PathPattern
+ PatternStep RelativePathPattern IdKeyPattern OptionalAssign
+ OptionalDefaultValue
+
+%type <orderSpec> OrderSpec
+%type <expressionList> ExpressionSequence FunctionArguments
+ DirElemContent AttrValueContent
+%type <orderSpecs> OrderSpecList OrderByClause MandatoryOrderByClause
+%type <functionArgument> Param
+%type <functionArguments> ParamList
+%type <itemType> KindTest ItemType AtomicType NodeTest NameTest WildCard NodeTestInAxisStep
+ ElementTest AttributeTest SchemaElementTest SchemaAttributeTest
+ TextTest CommentTest PITest DocumentTest AnyKindTest AnyAttributeTest
+%type <qName> ElementName QName VarName FunctionName PragmaName TypeName NCName
+ CaseVariable AttributeName OptionalTemplateName
+ TemplateName Mode OptionalMode
+%type <qNameVector> Modes OptionalModes
+%type <sequenceType> SequenceType SingleType TypeDeclaration
+%type <sval> URILiteral StringLiteral LexicalName
+%type <enums.Bool> IsInternal IsTunnel
+%type <enums.Double> OptionalPriority
+%type <enums.pathKind> MapOrSlash
+
+/* Operator Precendence
+ * See: http://www.w3.org/TR/xpath20/#parse-note-occurrence-indicators */
+%left STAR DIV
+%left PLUS MINUS
+
+%%
+
+/* Here, the grammar starts. In the brackets on the right you
+ * find the number of corresponding EBNF rule in the XQuery 1.0 specification. If it
+ * contains an X, it means the non-terminal has no counter part in the grammar, but
+ * exists for implementation purposes. */
+Module: VersionDecl LibraryModule /* [1] */
+| VersionDecl MainModule
+
+VersionDecl: /* empty */ /* [2] */
+| XQUERY VERSION StringLiteral Encoding Separator
+ {
+
+/* Suppress more compiler warnings about unused defines. */
+#if defined(YYNNTS) \
+ || defined(yyerrok) \
+ || defined(YYNSTATES) \
+ || defined(YYRHSLOC) \
+ || defined(YYRECOVERING) \
+ || defined(YYFAIL) \
+ || defined(YYERROR) \
+ || defined(YYNRULES) \
+ || defined(YYBACKUP) \
+ || defined(YYMAXDEPTH) \
+ || defined(yyclearin) \
+ || defined(YYERRCODE) \
+ || defined(YY_LOCATION_PRINT) \
+ || defined(YYLLOC_DEFAULT)
+#endif
+
+ if($3 != QLatin1String("1.0"))
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Version %1 is not supported. The supported "
+ "XQuery version is 1.0.")
+ .arg(formatData($3)),
+ ReportContext::XQST0031, &ryy);
+ }
+ }
+
+Encoding: /* empty */ /* [X] */
+| ENCODING StringLiteral
+ {
+ const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));
+
+ if(!encNameRegExp.exactMatch($2))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The encoding %1 is invalid. "
+ "It must contain Latin characters only, "
+ "must not contain whitespace, and must match "
+ "the regular expression %2.")
+ .arg(formatKeyword((yyvsp[(2) - (2)].sval)),
+ formatExpression(encNameRegExp.pattern())),
+ ReportContext::XQST0087, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+MainModule: Prolog QueryBody /* [3] */
+ {
+ /* In XSL-T, we can have dangling variable references, so resolve them
+ * before we proceed with other steps, such as checking circularity. */
+ if(parseInfo->isXSLT())
+ {
+ typedef QHash<QXmlName, Expression::Ptr> Hash;
+ const Hash::const_iterator end(parseInfo->unresolvedVariableReferences.constEnd());
+
+ for(Hash::const_iterator it(parseInfo->unresolvedVariableReferences.constBegin()); it != end; ++it)
+ {
+ const Expression::Ptr body(resolveVariable(it.key(), @$, parseInfo, true)); // TODO source locations vaise
+ Q_ASSERT(body);
+ it.value()->as<UnresolvedVariableReference>()->bindTo(body);
+ }
+ }
+
+ /* The UserFunction callsites aren't bound yet, so bind them(if possible!). */
+ {
+ const UserFunctionCallsite::List::const_iterator cend(parseInfo->userFunctionCallsites.constEnd());
+ UserFunctionCallsite::List::const_iterator cit(parseInfo->userFunctionCallsites.constBegin());
+ for(; cit != cend; ++cit) /* For each callsite. */
+ {
+ const UserFunctionCallsite::Ptr callsite(*cit);
+ Q_ASSERT(callsite);
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it) /* For each UserFunction. */
+ {
+ const FunctionSignature::Ptr sign((*it)->signature());
+ Q_ASSERT(sign);
+
+ if(callsite->isSignatureValid(sign))
+ {
+ callsite->setSource((*it),
+ parseInfo->allocateCacheSlots((*it)->argumentDeclarations().count()));
+ break;
+ }
+ }
+ if(it == end)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function with signature %1 is available")
+ .arg(formatFunction(callsite)),
+ ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ }
+
+ /* Mark callsites in UserFunction bodies as recursive, if they are. */
+ {
+ const UserFunction::List::const_iterator fend(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator fit(parseInfo->userFunctions.constBegin());
+ for(; fit != fend; ++fit)
+ {
+ CallTargetDescription::List signList;
+ signList.append((*fit)->signature());
+ CallTargetDescription::checkCallsiteCircularity(signList, (*fit)->body());
+ }
+ }
+
+ /* Now, check all global variables for circularity. This is done
+ * backwards because global variables are only in scope below them,
+ * in XQuery. */
+ {
+ const VariableDeclaration::List::const_iterator start(parseInfo->declaredVariables.constBegin());
+ VariableDeclaration::List::const_iterator it(parseInfo->declaredVariables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ if((*it)->type != VariableDeclaration::ExpressionVariable && (*it)->type != VariableDeclaration::GlobalVariable)
+ continue; /* We want to ignore 'external' variables. */
+
+ FunctionSignature::List signList;
+ checkVariableCircularity(*it, (*it)->expression(), (*it)->type, signList, parseInfo);
+ ExpressionFactory::registerLastPath((*it)->expression());
+ parseInfo->finalizePushedVariable(1, false); /* Warn if it's unused. */
+ }
+ }
+
+ /* Generate code for doing initial template name calling. One problem
+ * is that we compilation in the initial template name, since we throw away the
+ * code if we don't have the requested template. */
+ if(parseInfo->languageAccent == QXmlQuery::XSLT20
+ && !parseInfo->initialTemplateName.isNull()
+ && parseInfo->namedTemplates.contains(parseInfo->initialTemplateName))
+ {
+ parseInfo->queryBody = create(new CallTemplate(parseInfo->initialTemplateName,
+ WithParam::Hash()),
+ @$, parseInfo);
+ parseInfo->templateCalls.append(parseInfo->queryBody);
+ /* We just discard the template body that XSLTTokenizer generated. */
+ }
+ else
+ parseInfo->queryBody = $2;
+ }
+
+LibraryModule: ModuleDecl Prolog /* [4] */
+
+ModuleDecl: MODULE NAMESPACE NCNAME G_EQ URILiteral Separator /* [5] */
+ {
+ // TODO add to namespace context
+ parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace($3);
+ }
+
+Prolog: /* Empty. */ /* [6] */
+/* First part. */
+| Prolog DefaultNamespaceDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog Setter
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog NamespaceDecl
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace declarations must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog Import
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog TemplateDecl
+
+/* Second part. */
+| Prolog VarDecl
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+| Prolog FunctionDecl
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+| Prolog OptionDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ parseInfo->hasSecondPrologPart = true;
+ }
+
+/*
+ * declare template name theName
+ * {
+ * "expression"
+ * };
+ *
+ * or
+ *
+ * declare template name theName matches (pattern) mode modeName priority 123
+ * {
+ * "expression"
+ * };
+ *
+ */
+TemplateDecl: DECLARE TEMPLATE TemplateName
+ OptionalTemplateParameters
+ TypeDeclaration
+ EnclosedOptionalExpr Separator /* [X] */
+ {
+ Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, $5), @$, parseInfo));
+
+ registerNamedTemplate($3, typeCheckTemplateBody($6, $5, parseInfo),
+ parseInfo, @1, temp);
+ temp->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+ }
+| DECLARE TEMPLATE OptionalTemplateName
+ MATCHES LPAREN
+ {
+ parseInfo->isParsingPattern = true;
+ }
+ Pattern
+ {
+ parseInfo->isParsingPattern = false;
+ }
+ RPAREN
+ OptionalModes
+ OptionalPriority
+ OptionalTemplateParameters
+ TypeDeclaration
+ EnclosedOptionalExpr Separator /* [X] */
+ {
+ /* In this grammar branch, we're guaranteed to be a template rule, but
+ * may also be a named template. */
+
+ const ImportPrecedence ip = parseInfo->isFirstTemplate() ? 0 : parseInfo->currentImportPrecedence;
+ Expression::Ptr pattern($7);
+ const TemplatePattern::ID templateID = parseInfo->allocateTemplateID();
+
+ Template::Ptr templ(create(new Template(ip, $13), @$, parseInfo));
+ templ->body = typeCheckTemplateBody($14, $13, parseInfo);
+ templ->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+
+ TemplatePattern::Vector ourPatterns;
+ /* We do it as per 6.4 Conflict Resolution for Template Rules:
+ *
+ * "If the pattern contains multiple alternatives separated by |, then
+ * the template rule is treated equivalently to a set of template
+ * rules, one for each alternative. However, it is not an error if a
+ * node matches more than one of the alternatives." */
+ while(pattern->is(Expression::IDCombineNodes))
+ {
+ const Expression::List operands(pattern->operands());
+ pattern = operands.first();
+
+ loadPattern(operands.at(1), ourPatterns, templateID, $11, templ);
+ }
+
+ loadPattern(pattern, ourPatterns, templateID, $11, templ);
+
+ if(!$3.isNull())
+ registerNamedTemplate($3, $14, parseInfo, @1, templ);
+
+ /* Now, let's add it to all the relevant templates. */
+ for(int i = 0; i < $10.count(); ++i) /* For each mode. */
+ {
+ const QXmlName &modeName = $10.at(i);
+
+ if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all) && $10.count() > 1)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The keyword %1 cannot occur with any other mode name.")
+ .arg(formatKeyword(QLatin1String("#all"))),
+ ReportContext::XTSE0530,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ /* For each pattern the template use. */
+ const TemplateMode::Ptr mode(parseInfo->modeFor(modeName));
+ for(int t = 0; t < ourPatterns.count(); ++t)
+ mode->templatePatterns.append(ourPatterns.at(t));
+ }
+ }
+
+OptionalPriority: /* Empty. */ /* [X] */
+ {
+ $$ = std::numeric_limits<xsDouble>::quiet_NaN();
+ }
+
+| PRIORITY StringLiteral
+ {
+ const AtomicValue::Ptr val(Decimal::fromLexical($2));
+ if(val->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The value of attribute %1 must be of type %2, which %3 isn't.")
+ .arg(formatKeyword(QLatin1String("priority")),
+ formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsDecimal),
+ formatData($2)),
+ ReportContext::XTSE0530,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ $$ = val->as<Numeric>()->toDouble();
+ }
+
+OptionalTemplateName: /* Empty. */ /* [X] */
+ {
+ $$ = QXmlName();
+ }
+| TemplateName
+
+TemplateName: NAME ElementName
+ {
+ $$ = $2;
+ }
+
+Setter: BoundarySpaceDecl /* [7] */
+| DefaultCollationDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| BaseURIDecl
+| ConstructionDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| OrderingModeDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| EmptyOrderDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| CopyNamespacesDecl
+
+Import: SchemaImport /* [8] */
+| ModuleImport
+
+Separator: SEMI_COLON /* [9] */
+
+NamespaceDecl: DECLARE NAMESPACE NCNAME G_EQ URILiteral IsInternal Separator /* [10] */
+ {
+ if(!$6)
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+
+ if($3 == QLatin1String("xmlns"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to redeclare prefix %1.")
+ .arg(formatKeyword(QLatin1String("xmlns"))),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+ else if ($5 == CommonNamespaces::XML || $3 == QLatin1String("xml"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The prefix %1 can not be bound. By default, it is already bound "
+ "to the namespace %2.")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(CommonNamespaces::XML)),
+ ReportContext::XQST0070,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else if(parseInfo->declaredPrefixes.contains($3))
+ {
+ /* This includes the case where the user has bound a default prefix(such
+ * as 'local') and now tries to do it again. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 is already declared in the prolog.")
+ .arg(formatKeyword($3)),
+ ReportContext::XQST0033, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->declaredPrefixes.append($3);
+
+ if($5.isEmpty())
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(StandardNamespaces::UndeclarePrefix,
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix($3)));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(parseInfo->staticContext->namePool()->allocateBinding($3, $5));
+ }
+ }
+ }
+
+BoundarySpaceDecl: DECLARE BOUNDARY_SPACE BoundarySpacePolicy Separator /* [11] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare boundary-space"),
+ ReportContext::XQST0068, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setBoundarySpacePolicy($3);
+ parseInfo->registerDeclaration(ParserContext::BoundarySpaceDecl);
+ }
+ }
+
+BoundarySpacePolicy: STRIP /* [X] */
+ {
+ $$ = StaticContext::BSPStrip;
+ }
+
+| PRESERVE
+ {
+ $$ = StaticContext::BSPPreserve;
+ }
+
+DefaultNamespaceDecl: DeclareDefaultElementNamespace /* [12] */
+| DeclareDefaultFunctionNamespace
+
+DeclareDefaultElementNamespace: DECLARE DEFAULT ELEMENT NAMESPACE
+ URILiteral Separator /* [X] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default element namespace"),
+ ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5), StandardLocalNames::empty));
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultElementNamespace);
+ }
+ }
+
+DeclareDefaultFunctionNamespace: DECLARE DEFAULT FUNCTION NAMESPACE
+ URILiteral Separator /* [X] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default function namespace"),
+ ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setDefaultFunctionNamespace($5);
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultFunctionNamespace);
+ }
+ }
+
+OptionDecl: DECLARE OPTION ElementName StringLiteral Separator /* [13] */
+ {
+ if($3.prefix() == StandardPrefixes::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an option must have a prefix. "
+ "There is no default namespace for options."),
+ ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+OrderingModeDecl: DECLARE ORDERING OrderingMode Separator /* [14] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0065, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::OrderingModeDecl);
+ parseInfo->staticContext->setOrderingMode($3);
+ }
+ }
+
+OrderingMode: ORDERED
+ {
+ $$ = StaticContext::Ordered;
+ }
+| UNORDERED
+ {
+ $$ = StaticContext::Unordered;
+ }
+
+EmptyOrderDecl: DECLARE DEFAULT ORDER OrderingEmptySequence Separator /* [15] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default order"),
+ ReportContext::XQST0069, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::EmptyOrderDecl);
+ parseInfo->staticContext->setOrderingEmptySequence($4);
+ }
+ }
+
+OrderingEmptySequence: EMPTY LEAST /* [X] */
+ {
+ $$ = StaticContext::Least;
+ }
+| EMPTY GREATEST
+ {
+ $$ = StaticContext::Greatest;
+ }
+
+CopyNamespacesDecl: DECLARE COPY_NAMESPACES PreserveMode COMMA
+ InheritMode Separator /* [16] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare copy-namespaces"),
+ ReportContext::XQST0055, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::CopyNamespacesDecl);
+ }
+ }
+
+PreserveMode: PRESERVE /* [17] */
+ {
+ parseInfo->preserveNamespacesMode = true;
+ }
+
+| NO_PRESERVE
+ {
+ parseInfo->preserveNamespacesMode = false;
+ }
+
+InheritMode: INHERIT /* [18] */
+ {
+ parseInfo->inheritNamespacesMode = true;
+ }
+
+| NO_INHERIT
+ {
+ parseInfo->inheritNamespacesMode = false;
+ }
+
+DefaultCollationDecl: DECLARE DEFAULT COLLATION StringLiteral Separator /* [19] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default collation"),
+ ReportContext::XQST0038, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ const QUrl coll(resolveAndCheckCollation<ReportContext::XQST0038>($4, parseInfo, @$));
+
+ parseInfo->registerDeclaration(ParserContext::DefaultCollationDecl);
+ parseInfo->staticContext->setDefaultCollation(coll);
+ }
+ }
+
+BaseURIDecl: DECLARE BASEURI IsInternal URILiteral Separator /* [20] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$, $3);
+ if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare base-uri"),
+ ReportContext::XQST0032, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::BaseURIDecl);
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ QUrl toBeBase(AnyURI::toQUrl<ReportContext::XQST0046>($4, parseInfo->staticContext, &ryy));
+ /* Now we're guaranteed that base is a valid lexical representation, but it can still be relative. */
+
+ if(toBeBase.isRelative())
+ toBeBase = parseInfo->staticContext->baseURI().resolved(toBeBase);
+
+ parseInfo->staticContext->setBaseURI(toBeBase);
+ }
+ }
+
+SchemaImport: IMPORT SCHEMA SchemaPrefix URILiteral FileLocations Separator /* [21] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Import feature is not supported, "
+ "and therefore %1 declarations cannot occur.")
+ .arg(formatKeyword("import schema")),
+ ReportContext::XQST0009, fromYYLTYPE(@$, parseInfo));
+ }
+
+SchemaPrefix: /* empty */ /* [22] */
+| DEFAULT ELEMENT NAMESPACE
+| NAMESPACE NCNAME G_EQ
+
+ModuleImport: IMPORT MODULE ModuleNamespaceDecl URILiteral FileLocations Separator /* [23] */
+ {
+ if($4.isEmpty())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The target namespace of a %1 cannot be empty.")
+ .arg(formatKeyword("module import")),
+ ReportContext::XQST0088, fromYYLTYPE(@$, parseInfo));
+
+ }
+ else
+ {
+ /* This is temporary until we have implemented it. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The module import feature is not supported"),
+ ReportContext::XQST0016, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ModuleNamespaceDecl: /* empty */ /* [X] */
+| NAMESPACE NCNAME G_EQ
+
+FileLocations: /* empty */ /* [X] */
+| AT FileLocation
+
+FileLocation: URILiteral /* [X] */
+| FileLocation COMMA URILiteral
+
+VarDecl: DECLARE VARIABLE IsInternal DOLLAR VarName TypeDeclaration
+ VariableValue OptionalDefaultValue Separator /* [24] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
+ if(variableByName($5, parseInfo))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by name %1 has already "
+ "been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical($5))),
+ parseInfo->isXSLT() ? ReportContext::XTSE0630 : ReportContext::XQST0049,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ if($7) /* We got a value assigned. */
+ {
+ const Expression::Ptr checked
+ (TypeChecker::applyFunctionConversion($7, $6, parseInfo->staticContext,
+ $3 ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ $3 ? TypeChecker::Options(TypeChecker::CheckFocus | TypeChecker::AutomaticallyConvert) : TypeChecker::CheckFocus));
+
+ pushVariable($5, $6, checked, VariableDeclaration::GlobalVariable, @$, parseInfo);
+ parseInfo->declaredVariables.append(parseInfo->variables.last());
+ }
+ else /* We got an 'external' declaration. */
+ {
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable($5, $6));
+
+ if(varType)
+ {
+ /* We push the declaration such that we can see name clashes and so on, but we don't use it for tying
+ * any references to it. */
+ pushVariable($5, varType, Expression::Ptr(), VariableDeclaration::ExternalVariable, @$, parseInfo);
+ }
+ else if($8)
+ {
+ /* Ok, the xsl:param got a default value, we make it
+ * available as a regular variable declaration. */
+ // TODO turn into checked
+ pushVariable($5, $6, $8, VariableDeclaration::GlobalVariable, @$, parseInfo);
+ // TODO ensure that duplicates are trapped.
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No value is available for the external "
+ "variable by name %1.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ parseInfo->isXSLT() ? ReportContext::XTDE0050 : ReportContext::XPDY0002,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ }
+ }
+
+VariableValue: EXTERNAL /* [X] */
+ {
+ $$.reset();
+ }
+| ASSIGN ExprSingle
+ {
+ $$ = $2;
+ }
+
+OptionalDefaultValue: /* Empty. */ /* [X] */
+ {
+ $$.reset();
+ }
+| ASSIGN ExprSingle
+ {
+ $$ = $2;
+ }
+
+ConstructionDecl: DECLARE CONSTRUCTION ConstructionMode Separator /* [25] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0067, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::ConstructionDecl);
+ parseInfo->staticContext->setConstructionMode($3);
+ }
+ }
+
+ConstructionMode: STRIP /* [X] */
+ {
+ $$ = StaticContext::CMStrip;
+ }
+| PRESERVE
+ {
+ $$ = StaticContext::CMPreserve;
+ }
+
+FunctionDecl: DECLARE FUNCTION IsInternal FunctionName LPAREN ParamList RPAREN
+ {
+ $<enums.slot>$ = parseInfo->currentExpressionSlot() - $6.count();
+ }
+ TypeDeclaration FunctionBody Separator /* [26] */
+ {
+ if(!$3)
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
+
+ /* If FunctionBody is null, it is 'external', otherwise the value is the body. */
+ const QXmlName::NamespaceCode ns($4.namespaceURI());
+
+ if(parseInfo->isXSLT() && !$4.hasPrefix())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A stylesheet function must have a prefixed name."),
+ ReportContext::XTSE0740,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ if($10) /* We got a function body. */
+ {
+ if(ns == StandardNamespaces::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace for a user defined function "
+ "cannot be empty (try the predefined "
+ "prefix %1 which exists for cases "
+ "like this)")
+ .arg(formatKeyword("local")),
+ ReportContext::XQST0060, fromYYLTYPE(@$, parseInfo));
+ }
+ else if(XPathHelper::isReservedNamespace(ns))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace %1 is reserved; therefore "
+ "user defined functions may not use it. "
+ "Try the predefined prefix %2, which "
+ "exists for these cases.")
+ .arg(formatURI(parseInfo->staticContext->namePool(), ns), formatKeyword("local")),
+ parseInfo->isXSLT() ? ReportContext::XTSE0080 : ReportContext::XQST0045,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else if(parseInfo->moduleNamespace != StandardNamespaces::empty &&
+ ns != parseInfo->moduleNamespace)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace of a user defined "
+ "function in a library module must be "
+ "equivalent to the module namespace. "
+ "In other words, it should be %1 instead "
+ "of %2")
+ .arg(formatURI(parseInfo->staticContext->namePool(), parseInfo->moduleNamespace),
+ formatURI(parseInfo->staticContext->namePool(), ns)),
+ ReportContext::XQST0048, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ /* Apply function conversion such that the body matches the declared
+ * return type. */
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion($10, $9,
+ parseInfo->staticContext,
+ ReportContext::XPTY0004,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert |
+ TypeChecker::CheckFocus |
+ TypeChecker::GeneratePromotion)));
+
+ const int argCount = $6.count();
+ const FunctionSignature::Ptr sign(new FunctionSignature($4 /* name */,
+ argCount /* minArgs */,
+ argCount /* maxArgs */,
+ $9 /* returnType */));
+ sign->setArguments($6);
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it)
+ {
+ if(*(*it)->signature() == *sign)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A function already exists with "
+ "the signature %1.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), sign)),
+ parseInfo->isXSLT() ? ReportContext::XTSE0770 : ReportContext::XQST0034, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ VariableDeclaration::List argDecls;
+
+ for(int i = 0; i < argCount; ++i)
+ argDecls.append(parseInfo->variables.at(i));
+
+ if($<enums.slot>8 > -1)
+ {
+ /* We have allocated slots, so now push them out of scope. */
+ parseInfo->finalizePushedVariable(argCount);
+ }
+
+ parseInfo->userFunctions.append(UserFunction::Ptr(new UserFunction(sign, checked, $<enums.slot>8, argDecls)));
+ }
+ }
+ else /* We got an 'external' declaration. */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No external functions are supported. "
+ "All supported functions can be used directly, "
+ "without first declaring them as external"),
+ ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ParamList: /* empty */ /* [27] */
+ {
+ $$ = FunctionArgument::List();
+ }
+| Param
+ {
+ FunctionArgument::List l;
+ l.append($1);
+ $$ = l;
+ }
+| ParamList COMMA Param
+ {
+ FunctionArgument::List::const_iterator it($1.constBegin());
+ const FunctionArgument::List::const_iterator end($1.constEnd());
+
+ for(; it != end; ++it)
+ {
+ if((*it)->name() == $3->name())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An argument by name %1 has already "
+ "been declared. Every argument name "
+ "must be unique.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3->name())),
+ ReportContext::XQST0039, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ $1.append($3);
+ $$ = $1;
+ }
+
+Param: DOLLAR VarName TypeDeclaration /* [28] */
+ {
+ pushVariable($2, $3, Expression::Ptr(), VariableDeclaration::FunctionArgument, @$, parseInfo);
+ $$ = FunctionArgument::Ptr(new FunctionArgument($2, $3));
+ }
+
+FunctionBody: EXTERNAL /* [X] */
+ {
+ $$.reset();
+ }
+| EnclosedExpr
+
+EnclosedExpr: CURLY_LBRACE Expr CURLY_RBRACE /* [29] */
+ {
+ $$ = $2;
+ }
+
+QueryBody: Expr /* [30] */
+
+/**
+ * A pattern as found in for instance xsl:template/@match.
+ *
+ * @note When using this pattern, remember to set ParserContext::isParsingPattern.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#dt-pattern">XSL Transformations
+ * (XSLT) Version 2.0, 5.5.2 Syntax of Patterns</a>
+ */
+Pattern: PathPattern /* [XSLT20-1] */
+| Pattern BAR PathPattern
+ {
+ $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
+ }
+
+PathPattern: RelativePathPattern /* [XSLT20-2] */
+| SLASH
+ {
+ /* We write this into a node test. The spec says, 5.5.3 The Meaning of a Pattern:
+ * "Similarly, / matches a document node, and only a document node,
+ * because the result of the expression root(.)//(/) returns the root
+ * node of the tree containing the context node if and only if it is a
+ * document node." */
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisSelf, BuiltinTypes::document), @$, parseInfo);
+ }
+| SLASH RelativePathPattern
+ {
+ /* /axis::node-test
+ * =>
+ * axis::node-test[parent::document-node()]
+ *
+ * In practice it looks like this. $2 is:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep parent::element(b)
+ * AxisStep parent::element(a)
+ *
+ * and we want this:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep self::element(b)
+ * TruthPredicate
+ * AxisStep parent::element(a)
+ * AxisStep parent::document()
+ *
+ * So we want to rewrite the predicate deepest down into a
+ * another TruthPredicate containing the AxisStep.
+ *
+ * The simplest case where $2 is only an axis step is special. When $2 is:
+ *
+ * AxisStep self::element(a)
+ *
+ * we want:
+ *
+ * TruthPredicate
+ * AxisStep self::element(a)
+ * AxisStep parent::document()
+ */
+
+ /* First, find the target. */
+ Expression::Ptr target($2);
+
+ while(isPredicate(target->id()))
+ {
+ const Expression::Ptr candidate(target->operands().at(1));
+
+ if(isPredicate(candidate->id()))
+ target = candidate;
+ else
+ break; /* target is now the last predicate. */
+ }
+
+ if(target->is(Expression::IDAxisStep))
+ {
+ $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
+ parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
+ }
+ else
+ {
+ const Expression::List targetOperands(target->operands());
+ Expression::List newOps;
+ newOps.append(targetOperands.at(0));
+
+ newOps.append(create(GenericPredicate::create(targetOperands.at(1),
+ create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
+ parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo));
+
+ target->setOperands(newOps);
+ $$ = $2;
+ }
+ }
+| SLASHSLASH RelativePathPattern
+ {
+ /* //axis::node-test
+ * =>
+ * axis::node-test[parent::node()]
+ *
+ * Spec says: "//para matches any para element that has a parent node."
+ */
+ $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo),
+ parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
+ }
+| IdKeyPattern
+| IdKeyPattern SLASH RelativePathPattern
+ {
+ createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
+ }
+| IdKeyPattern SLASHSLASH RelativePathPattern
+ {
+ createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
+ }
+
+IdKeyPattern: FunctionCallExpr
+ {
+ const Expression::List ands($1->operands());
+ const FunctionSignature::Ptr signature($1->as<FunctionCall>()->signature());
+ const QXmlName name(signature->name());
+ const QXmlName key(StandardNamespaces::fn, StandardLocalNames::key);
+ const QXmlName id(StandardNamespaces::fn, StandardLocalNames::id);
+
+ if(name == id)
+ {
+ const Expression::ID id = ands.first()->id();
+ if(!isVariableReference(id) && id != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("When function %1 is used for matching inside a pattern, "
+ "the argument must be a variable reference or a string literal.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ else if(name == key)
+ {
+ if(ands.first()->id() != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a string literal, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ const Expression::ID id2 = ands.at(1)->id();
+ if(!isVariableReference(id2) &&
+ id2 != Expression::IDStringValue &&
+ id2 != Expression::IDIntegerValue &&
+ id2 != Expression::IDBooleanValue &&
+ id2 != Expression::IDFloat)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a literal or a variable reference, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(ands.count() == 3)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, function %1 cannot have a third argument.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ }
+ else
+ {
+ const FunctionSignature::Hash signs(parseInfo->staticContext->functionSignatures()->functionSignatures());
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, only function %1 "
+ "and %2, not %3, can be used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signs.value(id)),
+ formatFunction(parseInfo->staticContext->namePool(), signs.value(key)),
+ formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ $$ = $1;
+ }
+
+RelativePathPattern: PatternStep /* [XSLT20-3] */
+| RelativePathPattern SLASH PatternStep
+ {
+ $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
+ }
+| RelativePathPattern SLASHSLASH PatternStep
+ {
+ $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
+ }
+
+PatternStep: FilteredAxisStep
+ {
+ const Expression::Ptr expr(findAxisStep($1));
+
+ const QXmlNodeModelIndex::Axis axis = expr->as<AxisStep>()->axis();
+ AxisStep *const axisStep = expr->as<AxisStep>();
+
+ /* Here we constrain the possible axes, and we rewrite the axes as according
+ * to 5.5.3 The Meaning of a Pattern.
+ *
+ * However, we also rewrite axis child and attribute to axis self. The
+ * reason for this is that if we don't, we will match the children of
+ * the context node, instead of the context node itself. The formal
+ * definition of a pattern, root(.)//EE is insensitive to context,
+ * while the way we implement pattern, "the other way of seeing it",
+ * e.g from right to left, are very much. */
+
+ if(axisStep->nodeTest() == BuiltinTypes::document
+ || axis == QXmlNodeModelIndex::AxisChild)
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ else if(axis == QXmlNodeModelIndex::AxisAttribute)
+ {
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ /* Consider that the user write attribute::node(). This is
+ * semantically equivalent to attribute::attribute(), but since we have changed
+ * the axis to axis self, we also need to change the node test, such that we
+ * have self::attribute(). */
+ if(*axisStep->nodeTest() == *BuiltinTypes::node)
+ axisStep->setNodeTest(BuiltinTypes::attribute);
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, axis %1 cannot be used, "
+ "only axis %2 or %3 can.")
+ .arg(formatKeyword(AxisStep::axisName(axis)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisChild)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisAttribute))),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ $$ = $1;
+ }
+
+Expr: ExprSingle /* [31] */
+| ExpressionSequence
+ {
+ $$ = create(new ExpressionSequence($1), @$, parseInfo);
+ }
+
+ExpressionSequence: ExprSingle COMMA ExprSingle /* [X] */
+ {
+ Expression::List l;
+ l.append($1);
+ l.append($3);
+ $$ = l;
+ }
+| ExpressionSequence COMMA ExprSingle
+ {
+ $1.append($3);
+ $$ = $1;
+ }
+
+ExprSingle: OrExpr /* [32] */
+| FLWORExpr
+| QuantifiedExpr
+| TypeswitchExpr
+| IfExpr
+| AVT LPAREN AttrValueContent RPAREN
+ {
+ $$ = createDirAttributeValue($3, parseInfo, @$);
+ }
+
+OptionalModes: /* Empty. */ /* [X] */
+ {
+ QVector<QXmlName> result;
+ result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
+ $$ = result;
+ }
+| MODE Modes
+ {
+ $$ = $2;
+ }
+
+OptionalMode: /* Empty. */ /* [X] */
+ {
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ }
+| MODE Mode
+ {
+ $$ = $2;
+ }
+
+Modes: Mode
+ {
+ QVector<QXmlName> result;
+ result.append($1);
+ $$ = result;
+ }
+| Modes COMMA Mode
+ {
+ $1.append($3);
+ $$ = $1;
+ }
+
+Mode: QName /* [X] */
+ {
+ $$ = $1;
+ }
+| NCNAME
+ {
+ if($1 == QLatin1String("#current"))
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current);
+ else if($1 == QLatin1String("#default"))
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ else if($1 == QLatin1String("#all"))
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all);
+ else
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ if(!QXmlUtils::isNCName($1))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid template mode name.")
+ .arg(formatKeyword($1)),
+ ReportContext::XTSE0550,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
+ }
+ }
+
+
+FLWORExpr: ForClause /* [33] */
+| LetClause
+
+ForClause: FOR DOLLAR VarName TypeDeclaration
+ PositionalVar IN ExprSingle
+ {
+ /* We're pushing the range variable here, not the positional. */
+ $<expr>$ = pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
+ }
+ ForTail /* [34] */
+ {
+ Q_ASSERT($7);
+ Q_ASSERT($10);
+
+ /* We want the next last pushed variable, since we push the range variable after the
+ * positional variable. */
+ if($5 != -1 && parseInfo->variables.at(parseInfo->variables.count() -2)->name == $3)
+ {
+ /* Ok, a positional variable is used since its slot is not -1, and its name is equal
+ * to our range variable. This is an error. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of a variable bound in a for-expression must be different "
+ "from the positional variable. Hence, the two variables named %1 collide.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ ReportContext::XQST0089,
+ fromYYLTYPE(@$, parseInfo));
+
+ }
+
+ const Expression::Ptr retBody(create(new ForClause($<enums.slot>9, $<expr>8, $10, $5), @$, parseInfo));
+ ReturnOrderBy *const rob = locateReturnClause($10);
+
+ if(rob)
+ $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), retBody, rob), @$, parseInfo);
+ else
+ $$ = retBody;
+
+ parseInfo->finalizePushedVariable();
+
+ if($5 != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+
+ForTail: COMMA DOLLAR VarName TypeDeclaration
+ PositionalVar IN ExprSingle
+ {
+ pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
+ }
+ ForTail /* [X] */
+ {
+ $$ = create(new ForClause($<enums.slot>9, $<expr>7, $10, $5), @$, parseInfo);
+
+ parseInfo->finalizePushedVariable();
+
+ if($5 != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+
+| WhereClause
+| ForClause
+| LetClause
+
+PositionalVar: /* empty */ /* [35] */
+ {
+ $$ = -1;
+ }
+
+| AT DOLLAR VarName
+ {
+ pushVariable($3, CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(),
+ VariableDeclaration::PositionalVariable, @$, parseInfo);
+ $$ = parseInfo->currentPositionSlot();
+ }
+
+LetClause: LET IsInternal DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
+ {
+ $<expr>$ = pushVariable($4, quantificationType($5), $7, VariableDeclaration::ExpressionVariable, @$, parseInfo);
+ }
+ LetTail /* [36] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ Q_ASSERT(parseInfo->variables.top()->name == $4);
+ $$ = create(new LetClause($<expr>8, $9, parseInfo->variables.top()), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+LetTail: COMMA DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
+ { $<expr>$ = pushVariable($3, quantificationType($4), $6, VariableDeclaration::ExpressionVariable, @$, parseInfo);}
+ LetTail /* [X] */
+ {
+ Q_ASSERT(parseInfo->variables.top()->name == $3);
+ $$ = create(new LetClause($<expr>7, $8, parseInfo->variables.top()), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+| WhereClause
+| ForClause
+| LetClause
+
+WhereClause: OrderByClause RETURN ExprSingle /* [37] */
+ {
+ if($1.isEmpty())
+ $$ = $3;
+ else
+ $$ = createReturnOrderBy($1, $3, parseInfo->orderStability.pop(), @$, parseInfo);
+ }
+
+| WHERE ExprSingle OrderByClause RETURN ExprSingle
+ {
+ if($3.isEmpty())
+ $$ = create(new IfThenClause($2, $5, create(new EmptySequence, @$, parseInfo)), @$, parseInfo);
+ else
+ $$ = create(new IfThenClause($2, createReturnOrderBy($3, $5, parseInfo->orderStability.pop(), @$, parseInfo),
+ create(new EmptySequence, @$, parseInfo)),
+ @$, parseInfo);
+ }
+
+OrderByClause: /* Empty. */ /* [38] */
+ {
+ $$ = OrderSpecTransfer::List();
+ }
+| MandatoryOrderByClause
+
+MandatoryOrderByClause: OrderByInputOrder OrderSpecList
+ {
+ $$ = $2;
+ }
+
+OrderSpecList: OrderSpecList COMMA OrderSpec /* [39] */
+ {
+ OrderSpecTransfer::List list;
+ list += $1;
+ list.append($3);
+ $$ = list;
+ }
+| OrderSpec
+ {
+ OrderSpecTransfer::List list;
+ list.append($1);
+ $$ = list;
+ }
+
+OrderSpec: ExprSingle DirectionModifier EmptynessModifier CollationModifier /* [40] */
+ {
+ $$ = OrderSpecTransfer($1, OrderBy::OrderSpec($2, $3));
+ }
+
+DirectionModifier: /* Empty. */ /* [X] */
+ {
+ /* Where does the specification state the default value is ascending?
+ *
+ * It is implicit, in the first enumerated list in 3.8.3 Order By and Return Clauses:
+ *
+ * "If T1 and T2 are two tuples in the tuple stream, and V1 and V2 are the first pair
+ * of values encountered when evaluating their orderspecs from left to right for
+ * which one value is greater-than the other (as defined above), then:
+ *
+ * 1. If V1 is greater-than V2: If the orderspec specifies descending,
+ * then T1 precedes T2 in the tuple stream; otherwise, T2 precedes T1 in the tuple stream.
+ * 2. If V2 is greater-than V1: If the orderspec specifies descending,
+ * then T2 precedes T1 in the tuple stream; otherwise, T1 precedes T2 in the tuple stream."
+ *
+ * which means that if you don't specify anything, or you
+ * specify ascending, you get the same result.
+ */
+ $$ = OrderBy::OrderSpec::Ascending;
+ }
+
+| ASCENDING
+ {
+ $$ = OrderBy::OrderSpec::Ascending;
+ }
+
+| DESCENDING
+ {
+ $$ = OrderBy::OrderSpec::Descending;
+ }
+
+EmptynessModifier: /* Empty. */ /* [X] */
+ {
+ $$ = parseInfo->staticContext->orderingEmptySequence();
+ }
+| OrderingEmptySequence
+
+CollationModifier: /* Empty. */ /* [X] */
+| COLLATION URILiteral
+ {
+ if(parseInfo->isXSLT())
+ resolveAndCheckCollation<ReportContext::XTDE1035>($2, parseInfo, @$);
+ else
+ resolveAndCheckCollation<ReportContext::XQST0076>($2, parseInfo, @$);
+ }
+| INTERNAL COLLATION ExprSingle
+ {
+ /* We do nothing. We don't use collations, and we have this non-terminal
+ * in order to accept expressions. */
+ }
+
+OrderByInputOrder: STABLE ORDER BY /* [X] */
+ {
+ parseInfo->orderStability.push(OrderBy::StableOrder);
+ }
+| ORDER BY
+ {
+ parseInfo->orderStability.push(OrderBy::UnstableOrder);
+ }
+
+QuantifiedExpr: SomeQuantificationExpr /* [42] */
+| EveryQuantificationExpr
+
+SomeQuantificationExpr: SOME DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ SomeQuantificationTail /* [X] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Some, $<expr>6, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+SomeQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ $<expr>$ = pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ SomeQuantificationTail /* [X] */
+ {
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Some, $<expr>7, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+| SatisfiesClause
+
+EveryQuantificationExpr: EVERY DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ EveryQuantificationTail /* [X] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Every, $<expr>6, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+EveryQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ $<expr>$ = pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ EveryQuantificationTail /* [X] */
+ {
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Every, $<expr>7, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+| SatisfiesClause
+
+SatisfiesClause: SATISFIES ExprSingle /* [X] */
+ {
+ $$ = $2;
+ }
+
+/*
+ * Typeswitches are re-written to a combination between @c if clauses, <tt>instance of</tt>, and
+ * @c let bindings. For example, the query:
+ *
+ * @code
+ * typeswitch(input)
+ * case element() return <!-- a comment -->
+ * case $i as attribute(name) return name($i)
+ * default return "Didn't match"
+ * @endcode
+ *
+ * becomes:
+ *
+ * @code
+ * if(input instance of element())
+ * then <!-- a comment -->
+ * else if(input instance of attribute(name))
+ * then let $i as attribute(name) := input return name($i)
+ * else "Didn't match"
+ * @endcode
+ */
+
+TypeswitchExpr: TYPESWITCH LPAREN Expr RPAREN
+ {
+ parseInfo->typeswitchSource.push($3);
+ }
+ CaseClause /* [43] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ parseInfo->typeswitchSource.pop();
+ $$ = $6;
+ }
+
+CaseClause: CASE CaseVariable SequenceType /* [44] */
+ {
+ if(!$2.isNull())
+ {
+ pushVariable($2, $3, parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
+ }
+ }
+ RETURN ExprSingle
+ {
+ /* The variable shouldn't be in-scope for other case branches. */
+ if(!$2.isNull())
+ parseInfo->finalizePushedVariable();
+ }
+ CaseTail
+ {
+ const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), $3), @$, parseInfo));
+ $$ = create(new IfThenClause(instanceOf, $6, $8), @$, parseInfo);
+ }
+
+CaseTail: CaseClause /* [X] */
+| CaseDefault
+
+CaseVariable: /* Empty. */ /* [X] */
+ {
+ $$ = QXmlName();
+ }
+
+| DOLLAR ElementName AS
+ {
+ $$ = $2;
+ }
+
+CaseDefault: DEFAULT RETURN ExprSingle /* [X] */
+ {
+ $$ = $3;
+ }
+| DEFAULT DOLLAR ElementName
+ {
+ if(!$3.isNull())
+ {
+ pushVariable($3, parseInfo->typeswitchSource.top()->staticType(),
+ parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
+ }
+ }
+ RETURN ExprSingle
+ {
+ if(!$3.isNull())
+ parseInfo->finalizePushedVariable();
+ $$ = $6;
+ }
+
+IfExpr: IF LPAREN Expr RPAREN THEN ExprSingle ELSE ExprSingle /* [45] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo);
+ }
+
+OrExpr: AndExpr /* [46] */
+| OrExpr OR AndExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new OrExpression($1, $3), @$, parseInfo);
+ }
+
+AndExpr: ComparisonExpr /* [47] */
+| AndExpr AND ComparisonExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new AndExpression($1, $3), @$, parseInfo);
+ }
+
+ComparisonExpr: RangeExpr /* [48] */
+| ValueComp
+| GeneralComp
+| NodeComp
+
+RangeExpr: AdditiveExpr /* [49] */
+| AdditiveExpr TO AdditiveExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new RangeExpression($1, $3), @$, parseInfo);
+ }
+
+AdditiveExpr: MultiplicativeExpr /* [50] */
+| AdditiveExpr AdditiveOperator MultiplicativeExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
+ }
+
+AdditiveOperator: PLUS {$$ = AtomicMathematician::Add;} /* [X] */
+| MINUS {$$ = AtomicMathematician::Substract;}
+
+MultiplicativeExpr: UnionExpr /* [51] */
+| MultiplicativeExpr MultiplyOperator UnionExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
+ }
+
+MultiplyOperator: STAR {$$ = AtomicMathematician::Multiply;} /* [X] */
+| DIV {$$ = AtomicMathematician::Div;}
+| IDIV {$$ = AtomicMathematician::IDiv;}
+| MOD {$$ = AtomicMathematician::Mod;}
+
+UnionExpr: IntersectExceptExpr /* [52] */
+| UnionExpr UnionOperator IntersectExceptExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10
+ | QXmlQuery::XPath20
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector),
+ parseInfo, @$);
+ $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
+ }
+
+IntersectExceptExpr: InstanceOfExpr /* [53] */
+| IntersectExceptExpr IntersectOperator InstanceOfExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new CombineNodes($1, $2, $3), @$, parseInfo);
+ }
+
+UnionOperator: UNION /* [X] */
+| BAR
+
+IntersectOperator: INTERSECT /* [X] */
+ {
+ $$ = CombineNodes::Intersect;
+ }
+| EXCEPT
+ {
+ $$ = CombineNodes::Except;
+ }
+
+InstanceOfExpr: TreatExpr /* [54] */
+| TreatExpr INSTANCE OF SequenceType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new InstanceOf($1,
+ SequenceType::Ptr($4)), @$, parseInfo);
+ }
+
+TreatExpr: CastableExpr /* [55] */
+| CastableExpr TREAT AS SequenceType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new TreatAs($1, $4), @$, parseInfo);
+ }
+
+CastableExpr: CastExpr /* [56] */
+| CastExpr CASTABLE AS SingleType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new CastableAs($1, $4), @$, parseInfo);
+ }
+
+CastExpr: UnaryExpr /* [57] */
+| UnaryExpr CAST AS SingleType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new CastAs($1, $4), @$, parseInfo);
+ }
+
+UnaryExpr: ValueExpr /* [58] */
+| UnaryOperator UnaryExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new UnaryExpression($1, $2, parseInfo->staticContext), @$, parseInfo);
+ }
+
+UnaryOperator: PLUS /* [X] */
+ {
+ $$ = AtomicMathematician::Add;
+ }
+| MINUS
+ {
+ $$ = AtomicMathematician::Substract;
+ }
+
+ValueExpr: ValidateExpr /* [59] */
+| PathExpr
+| ExtensionExpr
+
+GeneralComp: RangeExpr GeneralComparisonOperator RangeExpr /* [60] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new GeneralComparison($1, $2, $3, parseInfo->isBackwardsCompat.top()), @$, parseInfo);
+ }
+
+GeneralComparisonOperator: G_EQ {$$ = AtomicComparator::OperatorEqual;} /* [X] */
+| G_NE {$$ = AtomicComparator::OperatorNotEqual;}
+| G_GE {$$ = AtomicComparator::OperatorGreaterOrEqual;}
+| G_GT {$$ = AtomicComparator::OperatorGreaterThan;}
+| G_LE {$$ = AtomicComparator::OperatorLessOrEqual;}
+| G_LT {$$ = AtomicComparator::OperatorLessThan;}
+
+ValueComp: RangeExpr ValueComparisonOperator RangeExpr /* [61] */
+ {
+ $$ = create(new ValueComparison($1, $2, $3), @$, parseInfo);
+ }
+
+ValueComparisonOperator: EQ {$$ = AtomicComparator::OperatorEqual;}
+| NE {$$ = AtomicComparator::OperatorNotEqual;}
+| GE {$$ = AtomicComparator::OperatorGreaterOrEqual;}
+| GT {$$ = AtomicComparator::OperatorGreaterThan;}
+| LE {$$ = AtomicComparator::OperatorLessOrEqual;}
+| LT {$$ = AtomicComparator::OperatorLessThan;}
+
+NodeComp: RangeExpr NodeOperator RangeExpr /* [62] */
+ {
+ $$ = create(new NodeComparison($1, $2, $3), @$, parseInfo);
+ }
+
+NodeOperator: IS {$$ = QXmlNodeModelIndex::Is;} /* [X] */
+| PRECEDES {$$ = QXmlNodeModelIndex::Precedes;}
+| FOLLOWS {$$ = QXmlNodeModelIndex::Follows;}
+
+ValidateExpr: ValidationMode EnclosedExpr /* [63] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. "
+ "Hence, %1-expressions may not be used.")
+ .arg(formatKeyword("validate")),
+ ReportContext::XQST0075, fromYYLTYPE(@$, parseInfo));
+ /*
+ $$ = Validate::create($2, $1, parseInfo->staticContext);
+ */
+ }
+
+/* "A validate expression may optionally specify a validation mode. The
+ default validation mode is strict." */
+ValidationMode: VALIDATE {$$ = Validate::Strict;} /* [64] */
+| VALIDATE STRICT {$$ = Validate::Strict;}
+| VALIDATE LAX {$$ = Validate::Lax;}
+
+ExtensionExpr: Pragmas EnclosedOptionalExpr /* [65] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ /* We don't support any pragmas, so we only do the
+ * necessary validation and use the fallback expression. */
+
+ if($2)
+ $$ = $2;
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("None of the pragma expressions are supported. "
+ "Therefore, a fallback expression "
+ "must be present"),
+ ReportContext::XQST0079, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+EnclosedOptionalExpr: CURLY_LBRACE /* empty */ CURLY_RBRACE /* [X] */
+ {
+ $$.reset();
+ }
+| CURLY_LBRACE Expr CURLY_RBRACE
+ {
+ $$ = $2;
+ }
+
+Pragmas: Pragmas Pragma /* [X] */
+| Pragma
+
+Pragma: PRAGMA_START PragmaName PragmaContents PRAGMA_END /* [66] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+
+PragmaContents: /* empty */ /* [67] */
+| StringLiteral
+
+PathExpr: SLASH RelativePathExpr /* [68] */
+ {
+ /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */
+ $$ = create(new Path(createRootExpression(parseInfo, @$), $2), @$, parseInfo);
+ }
+
+| SLASHSLASH RelativePathExpr
+ {
+ $$ = createSlashSlashPath(createRootExpression(parseInfo, @$), $2, @$, parseInfo);
+ }
+| SLASH
+ {
+ /* This is "/". That is, fn:root(self::node()) treat as document-node(). */
+ $$ = createRootExpression(parseInfo, @$);
+ }
+
+| RelativePathExpr
+ /* This is "step", simply. We let bison generate "$$ = $1". */
+
+RelativePathExpr: StepExpr /* [69] */
+| RelativePathExpr MapOrSlash StepExpr
+ {
+ $$ = create(new Path($1, $3, $2), @$, parseInfo);
+ }
+| RelativePathExpr MapOrSlash SORT MandatoryOrderByClause RETURN StepExpr END_SORT
+ {
+ const Expression::Ptr orderBy(createReturnOrderBy($4, $6, parseInfo->orderStability.pop(), @$, parseInfo));
+
+ ReturnOrderBy *const rob = orderBy->as<ReturnOrderBy>();
+ const Expression::Ptr path(create(new Path($1, orderBy, $2), @$, parseInfo));
+
+ $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), path, rob), @$, parseInfo);
+ }
+| RelativePathExpr SLASHSLASH StepExpr
+ {
+ $$ = createSlashSlashPath($1, $3, @$, parseInfo);
+ }
+
+StepExpr: FilteredAxisStep /* [70] */
+ {
+ $$ = NodeSortExpression::wrapAround($1, parseInfo->staticContext);
+ }
+| FilterExpr
+| CURRENT EnclosedExpr
+ {
+ $$ = create(new CurrentItemStore($2), @$, parseInfo);
+ }
+| XSLT_VERSION
+ {
+ const xsDouble version = $1.toDouble();
+
+ parseInfo->isBackwardsCompat.push(version != 2);
+
+ $<enums.Double>$ = version;
+ }
+ EnclosedExpr
+ {
+ if($<enums.Double>2 < 2)
+ $$ = createCompatStore($3, @$, parseInfo);
+ else
+ $$ = $3;
+ }
+| BASEURI StringLiteral CURLY_LBRACE Expr CURLY_RBRACE /* [X] */
+{
+ allowedIn(QXmlQuery::XSLT20, parseInfo, @$);
+ Q_ASSERT(!$2.isEmpty());
+ $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo);
+}
+
+| DECLARE NAMESPACE NCNAME G_EQ STRING_LITERAL CURLY_LBRACE /* [X] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$);
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5),
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix($3)));
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ }
+ Expr
+ CURLY_RBRACE
+ {
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ $$ = $8;
+ }
+| CALL_TEMPLATE ElementName LPAREN TemplateWithParameters RPAREN
+ {
+ $$ = create(new CallTemplate($2, parseInfo->templateWithParams), @$, parseInfo);
+ parseInfo->templateWithParametersHandled();
+ parseInfo->templateCalls.append($$);
+ }
+
+TemplateWithParameters:
+ {
+ parseInfo->startParsingWithParam();
+ }
+ TemplateParameters
+ {
+ parseInfo->endParsingWithParam();
+ }
+
+TemplateParameters: /* Empty. */ /* [X] */
+ {
+ }
+| TemplateParameter
+ {
+ }
+| TemplateParameters COMMA TemplateParameter
+ {
+ }
+
+OptionalTemplateParameters: /* Empty. */ /* [X] */
+ {
+ }
+| LPAREN TemplateParameters RPAREN
+ {
+ }
+
+TemplateParameter: IsTunnel DOLLAR VarName TypeDeclaration OptionalAssign
+ {
+ /* Note, this grammar rule is invoked for @c xsl:param @em and @c
+ * xsl:with-param. */
+ const bool isParsingWithParam = parseInfo->isParsingWithParam();
+
+ /**
+ * @c xsl:param doesn't make life easy:
+ *
+ * If it only has @c name, it's default value is an empty
+ * string(hence has type @c xs:string), but the value that
+ * (maybe) is supplied can be anything, typically a node.
+ *
+ * Therefore, for that very common case we can't rely on
+ * the Expression's type, but have to force it to item()*.
+ *
+ * So if we're supplied the type item()*, we pass a null
+ * SequenceType. TemplateParameterReference recognizes this
+ * and has item()* as its static type, regardless of if the
+ * expression has a more specific type.
+ */
+ SequenceType::Ptr type;
+
+ if(!$4->is(CommonSequenceTypes::ZeroOrMoreItems))
+ type = $4;
+
+ Expression::Ptr expr;
+
+ /* The default value is an empty sequence. */
+ if(!$5 && ((type && $4->cardinality().allowsEmpty())
+ || isParsingWithParam))
+ expr = create(new EmptySequence, @$, parseInfo);
+ else
+ expr = $5;
+
+ /* We ensure we have some type, so CallTemplate, Template and friends
+ * are happy. */
+ if(!isParsingWithParam && !type)
+ type = CommonSequenceTypes::ZeroOrMoreItems;
+
+ if($1)
+ /* TODO, handle tunnel parameters. */;
+ else
+ {
+ if((!isParsingWithParam && VariableDeclaration::contains(parseInfo->templateParameters, $3)) ||
+ (isParsingWithParam && parseInfo->templateWithParams.contains($3)))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Each name of a template parameter must be unique; %1 is duplicated.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ isParsingWithParam ? ReportContext::XTSE0670 : ReportContext::XTSE0580, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ if(isParsingWithParam)
+ parseInfo->templateWithParams[$3] = WithParam::Ptr(new WithParam($3, $4, expr));
+ else
+ {
+ Q_ASSERT(type);
+ pushVariable($3, type, expr, VariableDeclaration::TemplateParameter, @$, parseInfo);
+ parseInfo->templateParameters.append(parseInfo->variables.top());
+ }
+ }
+ }
+ }
+
+IsTunnel: /* Empty. */
+ {
+ $$ = false;
+ }
+| TUNNEL
+ {
+ $$ = true;
+ }
+
+OptionalAssign: /* Empty. */ /* [X] */
+ {
+ $$ = Expression::Ptr();
+ }
+| ASSIGN ExprSingle
+ {
+ $$ = $2;
+ }
+
+/**
+ * Controls whethers a path expression should sort its result. Used for
+ * implementing XSL-T's for-each.
+ */
+MapOrSlash: SLASH /* [X] */
+ {
+ $$ = Path::RegularPath;
+ }
+| MAP
+ {
+ $$ = Path::XSLTForEach;
+ }
+| FOR_APPLY_TEMPLATE
+ {
+ $$ = Path::ForApplyTemplate;
+ }
+
+FilteredAxisStep: AxisStep /* [X] */
+| FilteredAxisStep LBRACKET Expr RBRACKET
+ {
+ $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@$, parseInfo)), @$, parseInfo);
+ }
+
+AxisStep: ForwardStep /* [71] */
+| ReverseStep
+
+ForwardStep: Axis
+ {
+ if($1 == QXmlNodeModelIndex::AxisAttribute)
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ NodeTestInAxisStep /* [72] */
+ {
+ if($3)
+ {
+ /* A node test was explicitly specified. The un-abbreviated syntax was used. */
+ $$ = create(new AxisStep($1, $3), @$, parseInfo);
+ }
+ else
+ {
+ /* Quote from 3.2.1.1 Axes
+ *
+ * [Definition: Every axis has a principal node kind. If an axis
+ * can contain elements, then the principal node kind is element;
+ * otherwise, it is the kind of nodes that the axis can contain.] Thus:
+ * - For the attribute axis, the principal node kind is attribute.
+ * - For all other axes, the principal node kind is element. */
+
+ if($1 == QXmlNodeModelIndex::AxisAttribute)
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, BuiltinTypes::attribute), @$, parseInfo);
+ else
+ $$ = create(new AxisStep($1, BuiltinTypes::element), @$, parseInfo);
+ }
+
+ parseInfo->restoreNodeTestSource();
+ }
+| AbbrevForwardStep
+
+NodeTestInAxisStep: NodeTest
+| AnyAttributeTest
+
+Axis: AxisToken COLONCOLON /* [73] */
+ {
+ if($1 == QXmlNodeModelIndex::AxisNamespace)
+ {
+ /* We don't raise XPST0010 here because the namespace axis isn't an optional
+ * axis. It simply is not part of the XQuery grammar. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The %1-axis is unsupported in XQuery")
+ .arg(formatKeyword("namespace")),
+ ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ $$ = $1;
+
+ switch($1)
+ {
+ case QXmlNodeModelIndex::AxisAttribute:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XSLT20),
+ parseInfo, @$);
+ break;
+ }
+ case QXmlNodeModelIndex::AxisChild:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector
+ | QXmlQuery::XSLT20),
+ parseInfo, @$);
+ break;
+ }
+ default:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XSLT20),
+ parseInfo, @$);
+ }
+ }
+ }
+
+AxisToken: ANCESTOR_OR_SELF {$$ = QXmlNodeModelIndex::AxisAncestorOrSelf ;}
+| ANCESTOR {$$ = QXmlNodeModelIndex::AxisAncestor ;}
+| ATTRIBUTE {$$ = QXmlNodeModelIndex::AxisAttribute ;}
+| CHILD {$$ = QXmlNodeModelIndex::AxisChild ;}
+| DESCENDANT_OR_SELF {$$ = QXmlNodeModelIndex::AxisDescendantOrSelf;}
+| DESCENDANT {$$ = QXmlNodeModelIndex::AxisDescendant ;}
+| FOLLOWING {$$ = QXmlNodeModelIndex::AxisFollowing ;}
+| PRECEDING {$$ = QXmlNodeModelIndex::AxisPreceding ;}
+| FOLLOWING_SIBLING {$$ = QXmlNodeModelIndex::AxisFollowingSibling;}
+| PRECEDING_SIBLING {$$ = QXmlNodeModelIndex::AxisPrecedingSibling;}
+| PARENT {$$ = QXmlNodeModelIndex::AxisParent ;}
+| SELF {$$ = QXmlNodeModelIndex::AxisSelf ;}
+
+AbbrevForwardStep: AT_SIGN
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ NodeTest /* [72] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, @$);
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $3), @$, parseInfo);
+
+ parseInfo->restoreNodeTestSource();
+ }
+| NodeTest
+ {
+ ItemType::Ptr nodeTest;
+
+ if(parseInfo->isParsingPattern && *$1 == *BuiltinTypes::node)
+ nodeTest = BuiltinTypes::xsltNodeTest;
+ else
+ nodeTest = $1;
+
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisChild, nodeTest), @$, parseInfo);
+ }
+| AnyAttributeTest
+ {
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $1), @$, parseInfo);
+ }
+
+ReverseStep: AbbrevReverseStep /* [75] */
+
+AbbrevReverseStep: DOTDOT /* [77] */
+ {
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo);
+ }
+
+NodeTest: NameTest /* [78] */
+| KindTest
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ }
+
+NameTest: ElementName /* [79] */
+ {
+ $$ = QNameTest::create(parseInfo->nodeTestSource, $1);
+ }
+| WildCard
+
+WildCard: STAR /* [80] */
+ {
+ $$ = parseInfo->nodeTestSource;
+ }
+| ANY_LOCAL_NAME
+ {
+ const NamePool::Ptr np(parseInfo->staticContext->namePool());
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ const QXmlName::NamespaceCode ns(QNameConstructor::namespaceForPrefix(np->allocatePrefix($1), parseInfo->staticContext, &ryy));
+
+ $$ = NamespaceNameTest::create(parseInfo->nodeTestSource, ns);
+ }
+| ANY_PREFIX
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName($1);
+ $$ = LocalNameTest::create(parseInfo->nodeTestSource, c);
+ }
+
+FilterExpr: PrimaryExpr /* [81] */
+| FilterExpr LBRACKET Expr RBRACKET
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@4, parseInfo)), @$, parseInfo);
+ }
+
+PrimaryExpr: Literal /* [84] */
+| VarRef
+| ParenthesizedExpr
+| ContextItemExpr
+| FunctionCallExpr
+| OrderingExpr
+| Constructor
+| APPLY_TEMPLATE OptionalMode LPAREN TemplateWithParameters RPAREN
+ {
+ $$ = create(new ApplyTemplate(parseInfo->modeFor($2),
+ parseInfo->templateWithParams,
+ parseInfo->modeFor(QXmlName(StandardNamespaces::InternalXSLT,
+ StandardLocalNames::Default))),
+ @1, parseInfo);
+ parseInfo->templateWithParametersHandled();
+ }
+
+Literal: NumericLiteral /* [85] */
+| StringLiteral
+ {
+ $$ = create(new Literal(AtomicString::fromValue($1)), @$, parseInfo);
+ }
+
+NumericLiteral: XPATH2_NUMBER /* [86] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = createNumericLiteral<Double>($1, @$, parseInfo);
+ }
+| NUMBER
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = createNumericLiteral<Numeric>($1, @$, parseInfo);
+ }
+
+VarRef: DOLLAR VarName /* [87] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = resolveVariable($2, @$, parseInfo, false);
+ }
+
+VarName: NCNAME /* [88] */
+ {
+ /* See: http://www.w3.org/TR/xpath20/#id-variables */
+ $$ = parseInfo->staticContext->namePool()->allocateQName(QString(), $1);
+ }
+| QName
+ {
+ $$ = $1;
+ }
+
+ParenthesizedExpr: LPAREN Expr RPAREN /* [89] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = $2;
+ }
+| LPAREN RPAREN
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new EmptySequence, @$, parseInfo);
+ }
+
+ContextItemExpr: DOT /* [90] */
+ {
+ $$ = create(new ContextItem(), @$, parseInfo);
+ }
+
+OrderingExpr: OrderingMode EnclosedExpr /* [X] */
+ {
+ $$ = $2;
+ }
+
+FunctionCallExpr: FunctionName LPAREN FunctionArguments RPAREN /* [93] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ if(XPathHelper::isReservedNamespace($1.namespaceURI()) || $1.namespaceURI() == StandardNamespaces::InternalXSLT)
+ { /* We got a call to a builtin function. */
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ const Expression::Ptr
+ func(parseInfo->staticContext->
+ functionSignatures()->createFunctionCall($1, $3, parseInfo->staticContext, &ryy));
+
+ if(func)
+ $$ = create(func, @$, parseInfo);
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function by name %1 is available.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)),
+ ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ else /* It's a call to a function created with 'declare function'.*/
+ {
+ $$ = create(new UserFunctionCallsite($1, $3.count()), @$, parseInfo);
+
+ $$->setOperands($3);
+ parseInfo->userFunctionCallsites.append($$);
+ }
+ }
+
+FunctionArguments: /* empty */ /* [X] */
+ {
+ $$ = Expression::List();
+ }
+
+| ExprSingle
+ {
+ Expression::List list;
+ list.append($1);
+ $$ = list;
+ }
+
+| ExpressionSequence
+
+Constructor: DirectConstructor /* [94] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| ComputedConstructor
+/* The reason we cannot call alloweIn() as the action for ComputedConstructor,
+ * is that we use the computed constructors for XSL-T, and therefore generate
+ * INTERNAL tokens. */
+
+DirectConstructor: DirElemConstructor /* [95] */
+| DirCommentConstructor
+| DirPIConstructor
+
+/*
+ * Direct attribute constructors can contain embedded expressions, and for those namespace bindings
+ * on the same element needs to be in scope. For example:
+ *
+ * @code
+ * <element attribute="{prefix:nameTest}" xmlns:prefix="http://example.com/"/>
+ * @endcode
+ *
+ * Patternist is designed to do all name resolution at parse time so the subsequent code only has to
+ * deal with expanded QNames(which the QName class represents), and this presents a problem since
+ * the parser haven't even encountered the @c xmlns:prefix when resolving @c prefix in the name test.
+ *
+ * This is solved as follows:
+ *
+ * <ol>
+ * <li>Just before starting parsing the attributes, we call Tokenizer::commenceScanOnly().
+ * This switches the tokenizer to not tokenize embedded expressions in attributes,
+ * but to return them as strings, token type STRING_LITERAL.</li>
+ * <li>We parse all the attributes, and iterates over them, only caring about
+ * namespace bindings, and validates and adds them to the context.</li>
+ * <li>We call Tokenizer::resumeTokenizationFrom() from the previous position
+ * returned from Tokenizer::commenceScanOnly() and parses the attributes once more,
+ * but this time with tokenization of embedded expressions. Since we this time
+ * have the namespace bindings in place, everything resolves.</li>
+ * </ol>
+ *
+ * Saxon does this in a similar way. Study net.sf.saxon.expr.QueryParser::parseDirectElementConstructor().
+ *
+ * @see XQueryTokenizer::attributeAsRaw()
+ */
+DirElemConstructor: G_LT
+ LexicalName
+ {
+ $<enums.tokenizerPosition>$ = parseInfo->tokenizer->commenceScanOnly();
+ parseInfo->scanOnlyStack.push(true);
+ }
+
+ /* This list contains name/string pairs. No embedded
+ * expressions has been parsed. */
+ DirAttributeList
+
+ {
+ ++parseInfo->elementConstructorDepth;
+ Expression::List constructors;
+
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+
+ /* Fix up attributes and namespace declarations. */
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = $4.size();
+ QSet<QXmlName::PrefixCode> usedDeclarations;
+
+ /* Whether xmlns="" has been encountered. */
+ bool hasDefaultDeclaration = false;
+
+ /* For each attribute & namespace declaration, do: */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName($4.at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+
+ /* This can seem a bit weird. However, this name is ending up in a QXmlName
+ * which consider its prefix a... prefix. So, a namespace binding name can in some cases
+ * be a local name, but that's just as the initial syntactical construct. */
+ const QXmlName::LocalNameCode localName = namePool->allocatePrefix(strLocalName);
+
+ /* Not that localName is "foo" in "xmlns:foo" and that prefix is "xmlns". */
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardPrefixes::xmlns))
+ {
+ if(localName == StandardPrefixes::xmlns)
+ hasDefaultDeclaration = true;
+
+ /* We have a namespace declaration. */
+
+ const Expression::Ptr nsExpr($4.at(i).second);
+
+ const QString strNamespace(nsExpr->is(Expression::IDEmptySequence) ? QString() : nsExpr->as<Literal>()->item().stringValue());
+
+ const QXmlName::NamespaceCode ns = namePool->allocateNamespace(strNamespace);
+
+ if(ns == StandardNamespaces::empty)
+ {
+ if(localName != StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI cannot be the empty string when binding to a prefix, %1.")
+ .arg(formatURI(strPrefix)),
+ ReportContext::XQST0085, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ else if(!AnyURI::isValid(strNamespace))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid namespace URI.").arg(formatURI(strNamespace)),
+ ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(prefix == StandardPrefixes::xmlns && localName == StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to bind to the prefix %1")
+ .arg(formatKeyword("xmlns")),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(ns == StandardNamespaces::xml && localName != StandardPrefixes::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml)))
+ .arg(formatKeyword("xml")),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(localName == StandardPrefixes::xml && ns != StandardNamespaces::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml))),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+
+ QXmlName nb;
+
+ if(localName == StandardPrefixes::xmlns)
+ nb = QXmlName(ns, StandardLocalNames::empty);
+ else
+ nb = QXmlName(ns, StandardLocalNames::empty, localName);
+
+ if(usedDeclarations.contains(nb.prefix()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Two namespace declaration attributes have the same name: %1.")
+ .arg(formatKeyword(namePool->stringForPrefix(nb.prefix()))),
+ ReportContext::XQST0071, fromYYLTYPE(@$, parseInfo));
+
+ }
+ else
+ usedDeclarations.insert(nb.prefix());
+
+ /* If the user has bound the XML namespace correctly, we in either
+ * case don't want to output it.
+ *
+ * We only have to check the namespace parts since the above checks has ensured
+ * consistency in the prefix parts. */
+ if(ns != StandardNamespaces::xml)
+ {
+ /* We don't want default namespace declarations when the
+ * default namespace already is empty. */
+ if(!(ns == StandardNamespaces::empty &&
+ localName == StandardNamespaces::xmlns &&
+ resolver->lookupNamespaceURI(StandardPrefixes::empty) == StandardNamespaces::empty))
+ {
+ constructors.append(create(new NamespaceConstructor(nb), @$, parseInfo));
+ resolver->addBinding(nb);
+ }
+ }
+ }
+ }
+
+ if(parseInfo->elementConstructorDepth == 1 && !hasDefaultDeclaration)
+ {
+ /* TODO But mostly this isn't needed, since the default element
+ * namespace is empty? How does this at all work? */
+ const QXmlName def(resolver->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ constructors.append(create(new NamespaceConstructor(def), @$, parseInfo));
+ }
+
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ $<expressionList>$ = constructors;
+
+ /* Resolve the name of the element, now that the namespace attributes are read. */
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ const QXmlName ele = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>($2, parseInfo->staticContext, resolver, &ryy);
+ parseInfo->tagStack.push(ele);
+ }
+
+ parseInfo->tokenizer->resumeTokenizationFrom($<enums.tokenizerPosition>3);
+ }
+ POSITION_SET
+ DirAttributeList
+ DirElemConstructorTail /* [96] */
+ {
+ /* We add the content constructor after the attribute constructors. This might result
+ * in nested ExpressionSequences, but it will be optimized away later on. */
+
+ Expression::List attributes($<expressionList>5);
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = $7.size();
+ QSet<QXmlName> declaredAttributes;
+ declaredAttributes.reserve(len);
+
+ /* For each namespace, resolve its name(now that we have resolved the namespace declarations) and
+ * turn it into an attribute constructor. */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName($7.at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+ const QXmlName::LocalNameCode localName = namePool->allocateLocalName(strLocalName);
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardLocalNames::xmlns))
+ {
+ const Expression::ID id = $7.at(i).second->id();
+
+ if(id == Expression::IDStringValue || id == Expression::IDEmptySequence)
+ {
+ /* It's a namespace declaration, and we've already handled those above. */
+ continue;
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI must be a constant and cannot "
+ "use enclosed expressions."),
+ ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
+ }
+
+ }
+ else
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+ const QXmlName att = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>($7.at(i).first, parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(),
+ &ryy, true);
+ if(declaredAttributes.contains(att))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An attribute by name %1 has already appeared on this element.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), att)),
+ ReportContext::XQST0040, fromYYLTYPE(@$, parseInfo));
+
+ }
+ else
+ declaredAttributes.insert(att);
+
+ /* wrapLiteral() needs the SourceLocationReflection of the AttributeConstructor, but
+ * it's unknown inside the arguments to its constructor. Hence we have to do this workaround of setting
+ * it twice.
+ *
+ * The AttributeConstructor's arguments are just dummies. */
+ const Expression::Ptr ctor(create(new AttributeConstructor($7.at(i).second, $7.at(i).second), @$, parseInfo));
+
+ Expression::List ops;
+ ops.append(wrapLiteral(toItem(QNameValue::fromValue(namePool, att)), parseInfo->staticContext, ctor.data()));
+ ops.append($7.at(i).second);
+ ctor->setOperands(ops);
+
+ attributes.append(ctor);
+ }
+ }
+
+ Expression::Ptr contentOp;
+
+ if(attributes.isEmpty())
+ contentOp = $8;
+ else
+ {
+ attributes.append($8);
+ contentOp = create(new ExpressionSequence(attributes), @$, parseInfo);
+ }
+
+ const Expression::Ptr name(create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), parseInfo->tagStack.top()))), @$, parseInfo));
+ $$ = create(new ElementConstructor(name, contentOp, parseInfo->isXSLT()), @$, parseInfo);
+
+ /* Restore the old context. We don't want the namespaces
+ * to be in-scope for expressions appearing after the
+ * element they appeared on. */
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ parseInfo->tagStack.pop();
+
+ --parseInfo->elementConstructorDepth;
+ }
+
+DirElemConstructorTail: QUICK_TAG_END
+ {
+ $$ = create(new EmptySequence(), @$, parseInfo);
+ }
+| G_GT DirElemContent BEGIN_END_TAG ElementName G_GT
+ {
+ if(!$4.isLexicallyEqual(parseInfo->tagStack.top()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A direct element constructor is not "
+ "well-formed. %1 is ended with %2.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical(parseInfo->tagStack.top())),
+ formatKeyword(parseInfo->staticContext->namePool()->toLexical($4))),
+ ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if($2.isEmpty())
+ $$ = create(new EmptySequence(), @$, parseInfo);
+ else if($2.size() == 1)
+ $$ = $2.first();
+ else
+ $$ = create(new ExpressionSequence($2), @$, parseInfo);
+ }
+
+DirAttributeList: /* empty */ /* [97] */
+ {
+ $$ = AttributeHolderVector();
+ }
+| DirAttributeList Attribute
+ {
+ $1.append($2);
+ $$ = $1;
+ }
+
+Attribute: LexicalName G_EQ DirAttributeValue /* [X] */
+ {
+ $$ = qMakePair($1, $3);
+ }
+
+DirAttributeValue: QUOTE AttrValueContent QUOTE /* [98] */
+ {
+ $$ = createDirAttributeValue($2, parseInfo, @$);
+ }
+
+| APOS AttrValueContent APOS
+ {
+ $$ = createDirAttributeValue($2, parseInfo, @$);
+ }
+
+AttrValueContent: /* Empty. */ /* [X] */
+ {
+ $$ = Expression::List();
+ }
+| EnclosedExpr AttrValueContent
+ {
+ Expression::Ptr content($1);
+
+ if(parseInfo->isBackwardsCompat.top())
+ content = create(GenericPredicate::createFirstItem(content), @$, parseInfo);
+
+ $2.prepend(createSimpleContent(content, @$, parseInfo));
+ $$ = $2;
+ }
+| StringLiteral AttrValueContent
+ {
+ $2.prepend(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo));
+ $$ = $2;
+ }
+
+DirElemContent: /* empty */ /* [101] */
+ {
+ $$ = Expression::List();
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+| DirElemContent DirectConstructor
+ {
+ $1.append($2);
+ $$ = $1;
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+| DirElemContent StringLiteral
+ {
+ if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip &&
+ XPathHelper::isWhitespaceOnly($2))
+ {
+ $$ = $1;
+ }
+ else
+ {
+ $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
+ $$ = $1;
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ }
+| DirElemContent NON_BOUNDARY_WS
+ {
+ $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
+ $$ = $1;
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+| DirElemContent EnclosedExpr
+ {
+ /* We insert a text node constructor that send an empty text node between
+ * the two enclosed expressions, in order to ensure that no space is inserted.
+ *
+ * However, we only do it when we have no node constructors. */
+ if(parseInfo->isPreviousEnclosedExpr &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($2->staticType()->itemType()) &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($1.last()->staticType()->itemType()))
+ $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue(QString())), @$, parseInfo)), @$, parseInfo));
+ else
+ parseInfo->isPreviousEnclosedExpr = true;
+
+ $1.append(createCopyOf($2, parseInfo, @$));
+ $$ = $1;
+ }
+
+DirCommentConstructor: COMMENT_START COMMENT_CONTENT /* [103] */
+ {
+ $$ = create(new CommentConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo);
+ }
+
+DirPIConstructor: PI_START PI_TARGET PI_CONTENT /* [105] */
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+ NCNameConstructor::validateTargetName<StaticContext::Ptr,
+ ReportContext::XPST0003,
+ ReportContext::XPST0003>($2,
+ parseInfo->staticContext, &ryy);
+
+ $$ = create(new ProcessingInstructionConstructor(
+ create(new Literal(AtomicString::fromValue($2)), @$, parseInfo),
+ create(new Literal(AtomicString::fromValue($3)), @$, parseInfo)), @$, parseInfo);
+ }
+
+ComputedConstructor: CompDocConstructor /* [109] */
+| CompElemConstructor
+| CompAttrConstructor
+| CompTextConstructor
+| CompCommentConstructor
+| CompPIConstructor
+| CompNamespaceConstructor
+
+CompDocConstructor: DOCUMENT IsInternal EnclosedExpr /* [110] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ $$ = create(new DocumentConstructor($3), @$, parseInfo);
+ }
+
+CompElemConstructor: ELEMENT IsInternal CompElementName
+ {
+ /* This value is incremented before the action below is executed. */
+ ++parseInfo->elementConstructorDepth;
+ }
+ EnclosedOptionalExpr /* [111] */
+ {
+ Q_ASSERT(5);
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ Expression::Ptr effExpr;
+
+ if($5)
+ effExpr = createCopyOf($5, parseInfo, @$);
+ else
+ effExpr = create(new EmptySequence(), @$, parseInfo);
+
+ const QXmlName::NamespaceCode ns = parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty);
+
+ /* Ensure the default namespace gets counted as an in-scope binding, if such a one exists. If we're
+ * a child of another constructor, it has already been done. */
+ if(parseInfo->elementConstructorDepth == 1 && ns != StandardNamespaces::empty)
+ {
+ Expression::List exprList;
+
+ /* We append the namespace constructor before the body, in order to
+ * comply with QAbstractXmlPushHandler's contract. */
+ const QXmlName def(parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ exprList.append(create(new NamespaceConstructor(def), @$, parseInfo));
+
+ exprList.append(effExpr);
+
+ effExpr = create(new ExpressionSequence(exprList), @$, parseInfo);
+ }
+
+ --parseInfo->elementConstructorDepth;
+ $$ = create(new ElementConstructor($3, effExpr, parseInfo->isXSLT()), @$, parseInfo);
+ }
+
+IsInternal: /* Empty. */ /* [X] */
+ {
+ $$ = false;
+ }
+| INTERNAL
+ {
+ $$ = true;
+ }
+
+CompAttrConstructor: ATTRIBUTE
+ IsInternal
+ CompAttributeName
+ EnclosedOptionalExpr /* [113] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ const Expression::Ptr name(create(new AttributeNameValidator($3), @$, parseInfo));
+
+ if($4)
+ $$ = create(new AttributeConstructor(name, createSimpleContent($4, @$, parseInfo)), @$, parseInfo);
+ else
+ $$ = create(new AttributeConstructor(name, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
+ }
+
+CompTextConstructor: TEXT IsInternal EnclosedExpr /* [114] */
+ {
+ $$ = create(new TextNodeConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
+ }
+
+CompCommentConstructor: COMMENT IsInternal EnclosedExpr /* [115] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ $$ = create(new CommentConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
+ }
+
+CompPIConstructor: PROCESSING_INSTRUCTION CompPIName EnclosedOptionalExpr /* [116] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ if($3)
+ {
+ $$ = create(new ProcessingInstructionConstructor($2, createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
+ }
+ else
+ $$ = create(new ProcessingInstructionConstructor($2, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
+ }
+
+CompAttributeName: {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ ElementName
+ {
+ parseInfo->restoreNodeTestSource();
+ } /* [X] */
+ {
+ $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $2))), @$, parseInfo);
+ }
+| CompNameExpr
+
+CompElementName: ElementName /* [X] */
+ {
+ $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $1))), @$, parseInfo);
+ }
+| CompNameExpr
+
+CompNameExpr: EnclosedExpr
+ {
+ if(BuiltinTypes::xsQName->xdtTypeMatches($1->staticType()->itemType()))
+ $$ = $1;
+ else
+ {
+ $$ = create(new QNameConstructor($1,
+ parseInfo->staticContext->namespaceBindings()),
+ @$, parseInfo);
+ }
+ }
+
+/*
+ * We always create an NCNameConstructor here. If will be rewritten away if not needed.
+ */
+CompPIName: NCNAME
+ {
+ $$ = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo)), @$, parseInfo);
+ }
+| EnclosedExpr
+ {
+ $$ = create(new NCNameConstructor($1), @$, parseInfo);
+ }
+
+/*
+ * This expression is used for implementing XSL-T 2.0's xsl:namespace
+ * instruction.
+ */
+CompNamespaceConstructor: NAMESPACE EnclosedExpr EnclosedExpr /* [X] */
+{
+ $$ = create(new ComputedNamespaceConstructor($2, $3), @$, parseInfo);
+}
+
+SingleType: AtomicType /* [117] */
+ {
+ $$ = makeGenericSequenceType($1, Cardinality::exactlyOne());
+ }
+| AtomicType QUESTION
+ {
+ $$ = makeGenericSequenceType($1, Cardinality::zeroOrOne());
+ }
+
+TypeDeclaration: /* empty */ /* [118] */
+ {
+ $$ = CommonSequenceTypes::ZeroOrMoreItems;
+ }
+| AS SequenceType
+ {
+ $$ = $2;
+ }
+
+SequenceType: ItemType OccurrenceIndicator /* [119] */
+ {
+ $$ = makeGenericSequenceType($1, $2);
+ }
+
+| EMPTY_SEQUENCE EmptyParanteses
+ {
+ $$ = CommonSequenceTypes::Empty;
+ }
+
+OccurrenceIndicator: /* empty */ {$$ = Cardinality::exactlyOne();} /* [120] */
+| PLUS {$$ = Cardinality::oneOrMore();}
+| STAR {$$ = Cardinality::zeroOrMore();}
+| QUESTION {$$ = Cardinality::zeroOrOne();}
+
+ItemType: AtomicType /* [121] */
+| KindTest
+| AnyAttributeTest
+| ITEM EmptyParanteses
+ {
+ $$ = BuiltinTypes::item;
+ }
+
+AtomicType: ElementName /* [122] */
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($1));
+
+ if(!t)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name %1 does not refer to any schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)), ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
+ }
+ else if(BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(t))
+ $$ = AtomicType::Ptr(t);
+ else
+ {
+ /* Try to give an intelligent message. */
+ if(t->isComplexType())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an complex type. Casting to complex "
+ "types is not possible. However, casting "
+ "to atomic types such as %2 works.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t))
+ .arg(formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsInteger)),
+ ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not an atomic type. Casting "
+ "is only possible to atomic types.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t)),
+ ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ }
+
+/* This non-terminal does not contain SchemaAttributeTest and AttributeTest.
+ Those are in the AnyAttributeTest non-terminal. This is in order to get the axis
+ right for attribute tests in the abbreviated syntax. */
+KindTest: DocumentTest /* [123] */
+| ElementTest
+| SchemaElementTest
+| PITest
+| CommentTest
+| TextTest
+| AnyKindTest
+
+AnyKindTest: NODE EmptyParanteses /* [124] */
+ {
+ $$ = BuiltinTypes::node;
+ }
+
+DocumentTest: DOCUMENT_NODE EmptyParanteses /* [125] */
+ {
+ $$ = BuiltinTypes::document;
+ }
+
+| DOCUMENT_NODE LPAREN AnyElementTest RPAREN
+ {
+ // TODO support for document element testing
+ $$ = BuiltinTypes::document;
+ }
+
+AnyElementTest: ElementTest /* [X] */
+| SchemaElementTest
+
+TextTest: TEXT EmptyParanteses /* [126] */
+ {
+ $$ = BuiltinTypes::text;
+ }
+
+CommentTest: COMMENT EmptyParanteses /* [127] */
+ {
+ $$ = BuiltinTypes::comment;
+ }
+
+PITest: PROCESSING_INSTRUCTION EmptyParanteses /* [128] */
+ {
+ $$ = BuiltinTypes::pi;
+ }
+
+| PROCESSING_INSTRUCTION LPAREN NCNAME RPAREN
+ {
+ $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
+ }
+
+| PROCESSING_INSTRUCTION LPAREN StringLiteral RPAREN
+ {
+ if(QXmlUtils::isNCName($3))
+ {
+ $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid name for a "
+ "processing-instruction.")
+ .arg(formatKeyword($3)),
+ ReportContext::XPTY0004,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+AnyAttributeTest: AttributeTest
+| SchemaAttributeTest
+
+AttributeTest: ATTRIBUTE EmptyParanteses /* [129] */
+ {
+ $$ = BuiltinTypes::attribute;
+ }
+
+| ATTRIBUTE LPAREN STAR RPAREN
+ {
+ $$ = BuiltinTypes::attribute;
+ }
+
+| ATTRIBUTE LPAREN AttributeName RPAREN
+ {
+ $$ = QNameTest::create(BuiltinTypes::attribute, $3);
+ }
+| ATTRIBUTE LPAREN AttributeName COMMA TypeName RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+| ATTRIBUTE LPAREN STAR COMMA TypeName RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+SchemaAttributeTest: SCHEMA_ATTRIBUTE LPAREN ElementName RPAREN /* [131] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ $$.reset();
+ }
+
+ElementTest: ELEMENT EmptyParanteses /* [133] */
+ {
+ $$ = BuiltinTypes::element;
+ }
+
+| ELEMENT LPAREN STAR RPAREN
+ {
+ $$ = BuiltinTypes::element;
+ }
+
+| ELEMENT LPAREN ElementName RPAREN
+ {
+ $$ = QNameTest::create(BuiltinTypes::element, $3);
+ }
+
+| ELEMENT LPAREN ElementName COMMA TypeName OptionalQuestionMark RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(unknownType()
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+| ELEMENT LPAREN STAR COMMA TypeName OptionalQuestionMark RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an unknown schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+OptionalQuestionMark: /* Empty. */
+| QUESTION
+
+SchemaElementTest: SCHEMA_ELEMENT LPAREN ElementName RPAREN /* [135] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ $$.reset();
+ }
+
+EmptyParanteses: LPAREN RPAREN /* [X] */
+
+AttributeName: NCNAME /* [137] */
+ {
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
+ }
+
+| QName
+
+/*
+ * When a QName appear with no prefix, it uses a certain default namespace
+ * depending on where the QName occurs. These two rules, invoked in the appropriate
+ * contexts, performs this distinction.
+ */
+ElementName: NCNAME /* [138] */
+ {
+ if(parseInfo->nodeTestSource == BuiltinTypes::element)
+ $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), $1);
+ else
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
+ }
+| QName
+
+TypeName: ElementName /* [139] */
+
+FunctionName: NCName /* [X] */
+| QName
+
+NCName: NCNAME
+ {
+ $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), $1);
+ }
+| INTERNAL_NAME NCNAME
+ {
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, $2);
+ }
+
+LexicalName: NCNAME
+| QNAME
+
+PragmaName: NCNAME /* [X] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in "
+ "a namespace."),
+ ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
+ }
+| QName
+
+URILiteral: StringLiteral /* [140] */
+
+StringLiteral: STRING_LITERAL /* [144] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ }
+| XPATH2_STRING_LITERAL
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ }
+
+QName: QNAME /* [154] */
+ {
+
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ $$ = QNameConstructor::
+ expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>($1, parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(), &ryy);
+
+ }
+| CLARK_NAME
+ {
+ $$ = parseInfo->staticContext->namePool()->fromClarkName($1);
+ }
+
+%%
+
+QString Tokenizer::tokenToString(const Token &token)
+{
+ switch(token.type)
+ {
+ case NCNAME:
+ /* Fallthrough. */
+ case QNAME:
+ /* Fallthrough. */
+ case NUMBER:
+ /* Fallthrough. */
+ case XPATH2_NUMBER:
+ return token.value;
+ case STRING_LITERAL:
+ return QLatin1Char('"') + token.value + QLatin1Char('"');
+ default:
+ {
+ const QString raw(QString::fromLatin1(yytname[YYTRANSLATE(token.type)]));
+
+ /* Remove the quotes. */
+ if(raw.at(0) == QLatin1Char('"') && raw.length() > 1)
+ return raw.mid(1, raw.length() - 2);
+ else
+ return raw;
+ }
+ }
+}
+
+} /* namespace Patternist */
+
+QT_END_NAMESPACE
+
+// vim: et:ts=4:sw=4:sts=4:syntax=yacc
diff --git a/src/xmlpatterns/parser/qxquerytokenizer.cpp b/src/xmlpatterns/parser/qxquerytokenizer.cpp
new file mode 100644
index 0000000..13f5a6e
--- /dev/null
+++ b/src/xmlpatterns/parser/qxquerytokenizer.cpp
@@ -0,0 +1,2249 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QByteArray>
+
+#include "qquerytransformparser_p.h"
+
+#include "qxquerytokenizer_p.h"
+
+#include "qtokenlookup.cpp"
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+#define handleWhitespace() \
+{ \
+ const TokenType t = consumeWhitespace(); \
+ if(t != SUCCESS) \
+ return Token(t); \
+}
+
+XQueryTokenizer::XQueryTokenizer(const QString &query,
+ const QUrl &location,
+ const State startingState) : Tokenizer(location)
+ , m_data(query)
+ , m_length(query.length())
+ , m_state(startingState)
+ , m_pos(0)
+ , m_line(1)
+ , m_columnOffset(0)
+ , m_scanOnly(false)
+{
+ Q_ASSERT(location.isValid() || location.isEmpty());
+}
+
+const QChar XQueryTokenizer::current() const
+{
+ if(m_pos < m_length)
+ return m_data.at(m_pos);
+ else
+ return QChar();
+}
+
+char XQueryTokenizer::peekCurrent() const
+{
+ return current().toAscii();
+}
+
+int XQueryTokenizer::peekForColonColon() const
+{
+ /* Note, we don't modify m_pos in this function, so we need to do offset
+ * calculations. */
+ int pos = m_pos;
+
+ while(pos < m_length)
+ {
+ switch(m_data.at(pos).toAscii())
+ {
+ /* Fallthrough these four. */
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ case ':':
+ {
+ if(peekAhead((pos - m_pos) + 1) == ':')
+ return pos - m_pos;
+ /* Fallthrough. */
+ }
+ default:
+ return -1;
+ }
+ ++pos;
+ }
+
+ return -1;
+}
+
+Tokenizer::Token XQueryTokenizer::tokenAndChangeState(const TokenType code,
+ const State s,
+ const int advance)
+{
+ Q_ASSERT(advance >= 0);
+ m_pos += advance;
+ setState(s);
+ return Token(code);
+}
+
+Tokenizer::Token XQueryTokenizer::tokenAndChangeState(const TokenType code,
+ const QString &value,
+ const State s)
+{
+ setState(s);
+ return Token(code, value);
+}
+
+Tokenizer::Token XQueryTokenizer::tokenAndAdvance(const TokenType code,
+ const int advance)
+{
+ Q_ASSERT(advance >= 0);
+ m_pos += advance;
+ return Token(code);
+}
+
+QString XQueryTokenizer::normalizeEOL(const QString &input,
+ const CharacterSkips &characterSkips)
+{
+ const int len = input.count();
+ QString result;
+
+ /* The likely hood is rather high it'll be the same content. */
+ result.reserve(len);
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QChar &at = input.at(i);
+
+ if(characterSkips.contains(i))
+ {
+ result.append(at);
+ continue;
+ }
+ switch(input.at(i).unicode())
+ {
+ case '\r':
+ {
+ if(i + 1 < len && input.at(i + 1) == QLatin1Char('\n'))
+ ++i;
+
+ /* Else, fallthrough. */
+ }
+ case '\n':
+ {
+ result.append(QLatin1Char('\n'));
+ continue;
+ }
+ default:
+ {
+ result.append(at);
+ }
+ }
+ }
+
+ return result;
+}
+
+Tokenizer::TokenType XQueryTokenizer::consumeComment()
+{
+ /* Below, we return ERROR instead of END_OF_FILE such that the parser
+ * sees an invalid comment. */
+ while(m_pos < m_length)
+ {
+ switch(peekCurrent())
+ {
+ case ':':
+ {
+ ++m_pos; /* Consume ':' */
+ if(atEnd())
+ return ERROR;
+
+ if(peekCurrent() == ')')
+ {
+ ++m_pos; /* Consume ')' */
+ return SUCCESS; /* The comment closed nicely. */
+ }
+ continue; /* We don't want to increment m_pos twice. */
+ }
+ case '(':
+ { /* It looks like the start of a comment. */
+ ++m_pos;
+
+ if(atEnd())
+ return END_OF_FILE;
+ else if(peekCurrent() == ':')
+ {
+ /* And it is a nested comment -- parse it. */
+ const TokenType retval = consumeComment();
+ if(retval == SUCCESS)
+ continue; /* Continue with our "own" comment. */
+ else
+ return retval; /* Return the error in the nested comment. */
+ }
+ break;
+ }
+ case '\n':
+ /* Fallthrough. */
+ case '\r':
+ {
+ /* We want to count \r\n as a single line break. */
+ if(peekAhead() == '\n')
+ ++m_pos;
+
+ m_columnOffset = m_pos;
+ ++m_line;
+
+ break;
+ }
+ }
+ ++m_pos;
+ }
+
+ return ERROR; /* Error: we reached the end while inside a comment. */
+}
+
+bool XQueryTokenizer::consumeRawWhitespace()
+{
+ while(m_pos < m_length)
+ {
+ switch(peekCurrent())
+ {
+ case ' ':
+ case '\t':
+ break;
+ case '\n':
+ case '\r':
+ {
+ if(peekAhead() == '\n')
+ ++m_pos;
+
+ m_columnOffset = m_pos;
+ ++m_line;
+
+ break;
+ }
+ default:
+ return false;
+ }
+ ++m_pos;
+ }
+ return true;
+}
+
+Tokenizer::TokenType XQueryTokenizer::consumeWhitespace()
+{
+ while(m_pos < m_length)
+ {
+ switch(peekCurrent())
+ {
+ case ' ':
+ case '\t':
+ break;
+ case '\n':
+ case '\r':
+ {
+ /* We want to count \r\n as a single line break. */
+ if(peekAhead() == '\n')
+ ++m_pos;
+
+ m_columnOffset = m_pos;
+ ++m_line;
+
+ break;
+ }
+ case '(':
+ {
+ if(peekAhead() == ':')
+ {
+ m_pos += 2; /* Consume "(:" */
+
+ const TokenType comment = consumeComment();
+ if(comment == SUCCESS)
+ continue;
+ else
+ return comment;
+ }
+ }
+ default:
+ return SUCCESS;
+ }
+ ++m_pos;
+ }
+
+ return END_OF_FILE;
+}
+
+char XQueryTokenizer::peekAhead(const int length) const
+{
+ if(m_pos + length < m_length)
+ return m_data.at(m_pos + length).toAscii();
+ else
+ return 0;
+}
+
+Tokenizer::Token XQueryTokenizer::error()
+{
+ return Token(ERROR);
+}
+
+bool XQueryTokenizer::isDigit(const char ch)
+{
+ return ch >= '0' && ch <= '9';
+}
+
+/* Replace with function in QXmlUtils. Write test cases for this. */
+bool XQueryTokenizer::isNCNameStart(const QChar ch)
+{
+ if(ch == QLatin1Char('_'))
+ return true;
+
+ switch(ch.category())
+ {
+ case QChar::Letter_Lowercase:
+ case QChar::Letter_Uppercase:
+ case QChar::Letter_Other:
+ case QChar::Letter_Titlecase:
+ case QChar::Number_Letter:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool XQueryTokenizer::isNCNameBody(const QChar ch)
+{
+ switch(ch.unicode())
+ {
+ case '.':
+ case '_':
+ case '-':
+ return true;
+ }
+
+ switch(ch.category())
+ {
+ case QChar::Letter_Lowercase:
+ case QChar::Letter_Uppercase:
+ case QChar::Letter_Other:
+ case QChar::Letter_Titlecase:
+ case QChar::Number_Letter:
+ case QChar::Mark_SpacingCombining:
+ case QChar::Mark_Enclosing:
+ case QChar::Mark_NonSpacing:
+ case QChar::Letter_Modifier:
+ case QChar::Number_DecimalDigit:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool XQueryTokenizer::isPhraseKeyword(const TokenType code)
+{
+ switch(code)
+ {
+ /* Fallthrough all these. */
+ case CASTABLE:
+ case CAST:
+ case COPY_NAMESPACES:
+ case DECLARE:
+ case EMPTY:
+ case MODULE:
+ case IMPORT:
+ case INSTANCE:
+ case ORDER:
+ case ORDERING:
+ case XQUERY:
+ case STABLE:
+ case TREAT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool XQueryTokenizer::isOperatorKeyword(const TokenType code)
+{
+ switch(code)
+ {
+ /* Fallthrough all these. */
+ case AS:
+ case ASCENDING:
+ case AT:
+ case CASE:
+ case CAST:
+ case CASTABLE:
+ case EQ:
+ case EXTERNAL:
+ case GE:
+ case G_EQ:
+ case G_GT:
+ case G_LT:
+ case G_NE:
+ case GT:
+ case IN:
+ case INHERIT:
+ case INSTANCE:
+ case IS:
+ case ITEM:
+ case LE:
+ case LT:
+ case NE:
+ case NO_INHERIT:
+ case NO_PRESERVE:
+ case OF:
+ case PRESERVE:
+ case RETURN:
+ case STABLE:
+ case TO:
+ case TREAT:
+ return true;
+ default:
+ return false;
+ };
+}
+
+bool XQueryTokenizer::isTypeToken(const TokenType t)
+{
+ switch(t)
+ {
+ /* Fallthrough all these. */
+ case ATTRIBUTE:
+ case COMMENT:
+ case DOCUMENT:
+ case DOCUMENT_NODE:
+ case ELEMENT:
+ case ITEM:
+ case NODE:
+ case PROCESSING_INSTRUCTION:
+ case SCHEMA_ATTRIBUTE:
+ case SCHEMA_ELEMENT:
+ case TEXT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeNCNameOrQName()
+{
+ const int start = m_pos;
+
+ const Token t1 = tokenizeNCName();
+ if(t1.hasError())
+ return t1;
+
+ if(peekCurrent() != ':' || peekAhead() == '=')
+ return t1;
+
+ ++m_pos;
+
+ const Token t2 = tokenizeNCName();
+ if(t2.hasError())
+ return t2;
+ else
+ return Token(QNAME, m_data.mid(start, m_pos - start));
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeNumberLiteral()
+{
+ setState(Operator);
+ const int startPos = m_pos;
+ bool hasDot = false;
+ bool isXPath20 = false;
+
+ for(; m_pos < m_length; ++m_pos)
+ {
+ QChar ch(current());
+
+ char cell = ch.cell();
+
+ if(cell == 'e' || cell == 'E')
+ {
+ isXPath20 = true;
+ ++m_pos;
+ ch = current();
+
+ if(ch.row() != 0)
+ break;
+
+ cell = ch.cell();
+
+ if(cell == '+' || cell == '-')
+ continue;
+ }
+
+ if(isNCNameStart(ch))
+ return error();
+
+ if(cell < '0' || cell > '9')
+ {
+ if(cell == '.' && !hasDot)
+ hasDot = true;
+ else
+ break;
+ }
+ }
+
+ return Token(isXPath20 ? XPATH2_NUMBER : NUMBER, m_data.mid(startPos, m_pos - startPos));
+}
+
+QString XQueryTokenizer::tokenizeCharacterReference()
+{
+ Q_ASSERT(peekCurrent() == '&');
+
+ const int theEnd = m_data.indexOf(QLatin1Char(';'), m_pos + 1);
+
+ if(theEnd == -1) /* No ';' found, a syntax error. i18n. */
+ return QString();
+
+ QString content(m_data.mid(m_pos + 1, (theEnd - m_pos) - 1));
+ m_pos = theEnd;
+
+ const QChar charRef(charForReference(content));
+
+ if(!charRef.isNull())
+ return charRef;
+ else if(content.startsWith(QLatin1Char('#')))
+ {
+ int base;
+
+ /* It is only '#' or '#x'. */
+ if(content.length() < 2)
+ return QString();
+
+ /* We got a hex number if it starts with 'x', otherwise it's a decimal. */
+ if(content.at(1) == QLatin1Char('x'))
+ {
+ base = 16;
+ content = content.mid(2); /* Remove "#x". */
+ }
+ else
+ {
+ base = 10;
+ content = content.mid(1); /* Remove "#". */
+ }
+
+ bool conversionOK = false;
+ const int codepoint = content.toInt(&conversionOK, base);
+
+ if(conversionOK)
+ {
+ const QChar ch(codepoint);
+
+ if(ch.isNull())
+ {
+ /* We likely have something which require surrogate pairs. */
+ QString result;
+ result += QChar(QChar::highSurrogate(codepoint));
+ result += QChar(QChar::lowSurrogate(codepoint));
+ return result;
+ }
+ else
+ return ch;
+ }
+ else
+ return QString();
+ }
+ else
+ return QString();
+}
+
+int XQueryTokenizer::scanUntil(const char *const content)
+{
+ const int end = m_data.indexOf(QString::fromLatin1(content), m_pos);
+
+ if(end == -1)
+ return -1;
+ else
+ {
+ const int len = end - m_pos;
+ m_pos += len;
+ return len;
+ }
+}
+
+QChar XQueryTokenizer::charForReference(const QString &reference)
+{
+ if(m_charRefs.isEmpty())
+ {
+ /* Initialize. */
+ m_charRefs.reserve(5);
+ m_charRefs.insert(QLatin1String("lt"), QLatin1Char('<'));
+ m_charRefs.insert(QLatin1String("gt"), QLatin1Char('>'));
+ m_charRefs.insert(QLatin1String("amp"), QLatin1Char('&'));
+ m_charRefs.insert(QLatin1String("quot"), QLatin1Char('"'));
+ m_charRefs.insert(QLatin1String("apos"), QLatin1Char('\''));
+ }
+
+ return m_charRefs.value(reference);
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeStringLiteral()
+{
+ const QChar delimiter(current());
+ /* We cannot unfortunately just scan and then do mid(),
+ * since we can encounter character references. */
+ QString result;
+
+ /* This is more likely than QString's default allocation. */
+ result.reserve(8);
+
+ CharacterSkips skipEOLNormalization;
+
+ /* Advance over the initial quote character. */
+ ++m_pos;
+
+ for(; m_pos < m_length; ++m_pos)
+ {
+ const QChar c(current());
+
+ if(c == QLatin1Char('&'))
+ {
+ const QString charRef(tokenizeCharacterReference());
+
+ if(charRef.isNull())
+ return error();
+ else
+ {
+ skipEOLNormalization.insert(result.count());
+ result.append(charRef);
+ }
+
+ }
+ else if(c == delimiter)
+ {
+ /* Maybe the escaping mechanism is used. For instance, "s""s"
+ * has the value `s"s'. */
+ ++m_pos;
+
+ if(current() == delimiter) /* Double quote. */
+ result += delimiter;
+ else
+ return Token(STRING_LITERAL, normalizeEOL(result, skipEOLNormalization));
+ }
+ else
+ result += c;
+ }
+
+ return error();
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeNCName()
+{
+ const int startPos = m_pos;
+
+ if(m_pos < m_length && isNCNameStart(current()))
+ {
+ ++m_pos;
+
+ for(; m_pos < m_length; ++m_pos)
+ {
+ if(!isNCNameBody(current()))
+ break;
+ }
+
+ return Token(NCNAME, m_data.mid(startPos, m_pos - startPos));
+ }
+ else
+ return error();
+}
+
+bool XQueryTokenizer::aheadEquals(const char *const chs,
+ const int len,
+ const int offset) const
+{
+ Q_ASSERT(len > 0);
+ Q_ASSERT(qstrlen(chs) == uint(len));
+
+ if(m_pos + len >= m_length)
+ return false;
+
+ for(int i = offset; i < (len + offset); ++i)
+ {
+ if(m_data.at(m_pos + i).toAscii() != chs[i - offset])
+ return false;
+ }
+
+ return true;
+}
+
+const TokenMap *XQueryTokenizer::lookupKeyword(const QString &keyword)
+{
+ return TokenLookup::value(keyword.toAscii().constData(), keyword.length());
+}
+
+XQueryTokenizer::State XQueryTokenizer::state() const
+{
+ return m_state;
+}
+
+void XQueryTokenizer::setState(const State s)
+{
+ m_state = s;
+}
+
+void XQueryTokenizer::pushState(const State s)
+{
+ m_stateStack.push(s);
+}
+
+void XQueryTokenizer::pushState()
+{
+ m_stateStack.push(m_state);
+}
+
+void XQueryTokenizer::popState()
+{
+ /* QStack::pop() asserts if it's empty, so we need to check
+ * it, since we might receive unbalanced curlies. */
+ if(!m_stateStack.isEmpty())
+ m_state = m_stateStack.pop();
+}
+
+Tokenizer::Token XQueryTokenizer::nextToken()
+{
+ switch(state())
+ {
+ /* We want to skip or do special whitespace handling for these
+ * states. So fallthrough all of the following. */
+ case AposAttributeContent:
+ case Axis:
+ case ElementContent:
+ case EndTag:
+ case Pragma:
+ case PragmaContent:
+ case ProcessingInstructionName:
+ case QuotAttributeContent:
+ case StartTag:
+ case XMLComment:
+ break;
+ default:
+ handleWhitespace();
+ }
+
+ switch(state())
+ {
+ case XMLSpaceDecl:
+ /* Fallthrough. */
+ case NamespaceKeyword:
+ {
+ switch(peekCurrent())
+ {
+ case ',':
+ return tokenAndAdvance(COMMA);
+ case '"':
+ /* Fallthrough. */
+ case '\'':
+ {
+ setState(NamespaceDecl);
+ return tokenizeStringLiteral();
+ }
+ }
+
+ const Token id(tokenizeNCName());
+
+ if(id.type != NCNAME)
+ return id;
+
+ const TokenMap *const keyword = lookupKeyword(id.value);
+ if(keyword)
+ {
+ switch(keyword->token)
+ {
+ case INHERIT:
+ /* Fallthrough. */
+ case NO_INHERIT:
+ {
+ setState(Default);
+ break;
+ }
+ case NAMESPACE:
+ {
+ setState(NamespaceDecl);
+ break;
+ }
+ case ORDERED:
+ /* Fallthrough. */
+ case UNORDERED:
+ /* Fallthrough. */
+ case STRIP:
+ {
+ setState(Default);
+ break;
+ }
+ case PRESERVE:
+ {
+ if(state() != NamespaceKeyword)
+ setState(Default);
+ }
+ default:
+ break;
+ }
+
+ return Token(keyword->token);
+ }
+ else
+ return id;
+
+ Q_ASSERT(false);
+ }
+ case NamespaceDecl:
+ {
+ switch(peekCurrent())
+ {
+ case '=':
+ return tokenAndAdvance(G_EQ);
+ case ';':
+ return tokenAndChangeState(SEMI_COLON, Default);
+ case '\'':
+ /* Fallthrough. */
+ case '\"':
+ return tokenizeStringLiteral();
+ }
+
+ const Token nc(tokenizeNCName());
+
+ handleWhitespace();
+
+ const char pc = peekCurrent();
+ const TokenMap* const t = lookupKeyword(nc.value);
+
+ if(pc == '\'' || (pc == '"' && t))
+ return tokenAndChangeState(t->token, Default, 0);
+ else
+ return nc;
+
+ Q_ASSERT(false);
+ }
+ case Axis:
+ {
+ if(peekCurrent() == ':')
+ {
+ Q_ASSERT(peekAhead() == ':');
+ m_pos += 2;
+ setState(AfterAxisSeparator);
+ return Token(COLONCOLON);
+ }
+ /* Fallthrough. */
+ }
+ case AfterAxisSeparator:
+ /* Fallthrough. */
+ case Default:
+ /* State Operator and state Default have a lot of tokens in common except
+ * for minor differences. So we treat them the same way, and sprinkles logic
+ * here and there to handle the small differences. */
+ /* Fallthrough. */
+ case Operator:
+ {
+ switch(peekCurrent())
+ {
+ case '=':
+ return tokenAndChangeState(G_EQ, Default);
+ case '-':
+ return tokenAndChangeState(MINUS, Default);
+ case '+':
+ return tokenAndChangeState(PLUS, Default);
+ case '[':
+ return tokenAndChangeState(LBRACKET, Default);
+ case ']':
+ return tokenAndChangeState(RBRACKET, Operator);
+ case ',':
+ return tokenAndChangeState(COMMA, Default);
+ case ';':
+ return tokenAndChangeState(SEMI_COLON, Default);
+ case '$':
+ return tokenAndChangeState(DOLLAR, VarName);
+ case '|':
+ return tokenAndChangeState(BAR, Default);
+ case '?':
+ return tokenAndChangeState(QUESTION, Operator);
+ case ')':
+ return tokenAndChangeState(RPAREN, Operator);
+ case '@':
+ return tokenAndChangeState(AT_SIGN, Default);
+ /* Fallthrough all these. */
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '0':
+ return tokenizeNumberLiteral();
+ case '.':
+ {
+ const char next = peekAhead();
+ if(next == '.')
+ return tokenAndChangeState(DOTDOT, Operator, 2);
+ /* .5 is allowed, as short form for 0.5:
+ * <tt>[142] DecimalLiteral ::= ("." Digits) | (Digits "." [0-9]*)</tt>
+ */
+ else if(isDigit(next))
+ return tokenizeNumberLiteral();
+ else
+ return tokenAndChangeState(DOT, Operator);
+ }
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ {
+ setState(Operator);
+ return tokenizeStringLiteral();
+
+ }
+ case '(':
+ {
+ if(peekAhead() == '#')
+ return tokenAndChangeState(PRAGMA_START, Pragma, 2);
+ else
+ return tokenAndChangeState(LPAREN, Default);
+ }
+ case '*':
+ {
+ if(peekAhead() == ':')
+ {
+ m_pos += 2; /* Consume *:. */
+ const Token nc = tokenizeNCName();
+
+ if(nc.hasError())
+ return error();
+ else
+ return tokenAndChangeState(ANY_PREFIX, nc.value, Operator);
+ }
+ else
+ return tokenAndChangeState(STAR, state() == Default ? Operator : Default);
+ }
+ case ':':
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return tokenAndChangeState(ASSIGN, Default, 2);
+ case ':':
+ return tokenAndChangeState(COLONCOLON, Default, 2);
+ default:
+ return error();
+ }
+ }
+ case '!':
+ {
+ if(peekAhead() == '=')
+ return tokenAndChangeState(G_NE, Default, 2);
+ else
+ return error();
+ }
+ case '<':
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return tokenAndChangeState(G_LE, Default, 2);
+ case '<':
+ return tokenAndChangeState(PRECEDES, Default, 2);
+ case '?':
+ {
+ pushState(Operator);
+ return tokenAndChangeState(PI_START, ProcessingInstructionName, 2);
+ }
+ case '!':
+ {
+ if(aheadEquals("!--", 3))
+ {
+ m_pos += 3; /* Consume "!--". */
+ pushState(Operator);
+ return tokenAndChangeState(COMMENT_START, XMLComment);
+ }
+ /* Fallthrough. It's a syntax error, and this is a good way to report it. */
+ }
+ default:
+ {
+ if((m_pos + 1) < m_length && isNCNameStart(m_data.at(m_pos + 1)))
+ {
+ /* We assume it's an element constructor. */
+ pushState(Operator);
+ }
+
+ return tokenAndChangeState(G_LT, state() == Operator ? Default : StartTag);
+ }
+ }
+ }
+ case '>':
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return tokenAndChangeState(G_GE, Default, 2);
+ case '>':
+ return tokenAndChangeState(FOLLOWS, Default, 2);
+ default:
+ return tokenAndChangeState(G_GT, Default);
+ }
+ }
+ case '/':
+ {
+ if(peekAhead() == '/')
+ return tokenAndChangeState(SLASHSLASH, Default, 2);
+ else
+ return tokenAndChangeState(SLASH, Default);
+ }
+ case '{':
+ {
+ pushState(Operator);
+ return tokenAndChangeState(CURLY_LBRACE, Default);
+ }
+ case '}':
+ {
+ popState();
+
+ return tokenAndAdvance(CURLY_RBRACE);
+ }
+ }
+
+ /* Ok. We're in state Default or Operator, and it wasn't a simple
+ * character. */
+
+ const Token id(tokenizeNCName());
+
+ if(id.type != NCNAME)
+ return id;
+
+ const TokenMap *const keyword = lookupKeyword(id.value);
+
+ if(state() == Operator)
+ {
+ if(keyword)
+ {
+ if(keyword->token == DEFAULT || keyword->token == ASCENDING || keyword->token == DESCENDING)
+ setState(Operator);
+ else if(keyword->token == RETURN)
+ setState(Default);
+ else if(isPhraseKeyword(keyword->token))
+ {
+ const TokenType ws = consumeWhitespace();
+ if(ws == ERROR)
+ return error();
+
+ const Token id2(tokenizeNCName());
+ const TokenMap *const keyword2 = lookupKeyword(id2.value);
+
+ if(keyword2)
+ {
+ if(keyword->token == TREAT && keyword2->token == AS)
+ setState(ItemType);
+ else if (keyword->token == CAST || (keyword->token == CASTABLE && keyword2->token == AS) || keyword2->token == BY)
+ setState(Default);
+
+ m_tokenStack.push(Token(keyword2->token));
+ }
+ else
+ m_tokenStack.push(id2);
+
+ return Token(keyword->token);
+ }
+ else
+ {
+ /* Such that we tokenize the second token in "empty greatest". */
+ if(keyword->token != EMPTY)
+ setState(Default);
+ }
+
+ if(keyword->token == AS || keyword->token == CASE)
+ setState(ItemType);
+
+ return Token(keyword->token);
+ }
+ else
+ return id;
+ }
+
+ Q_ASSERT(state() == Default || state() == Axis || state() == AfterAxisSeparator);
+
+ /*
+ * This is hard. Consider this:
+ *
+ * Valid: child ::nameTest
+ * Valid: child:: nameTest
+ * Syntax Error: child :localName
+ * Syntax Error: child: localName
+ *
+ * Consider "child ::name". Right now, we're here:
+ * ^
+ * We don't know whether "child" is a prefix and hence the whitespace is invalid,
+ * or whether it's an axis and hence skippable. */
+ {
+ const int wsLength = peekForColonColon();
+ /* We cannot call handleWhitespace() because it returns on
+ * END_OF_FILE, and we have parsed up keyword, and we need to
+ * deal with that.
+ *
+ * If we have a colon colon, which means the whitespace is
+ * allowed, we skip it. */
+ if(wsLength != -1)
+ m_pos += wsLength;
+ }
+
+ /* Handle name tests. */
+ if(peekCurrent() == ':')
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return id;
+ case '*':
+ {
+ m_pos += 2;
+ return tokenAndChangeState(ANY_LOCAL_NAME, id.value, Operator);
+ }
+ case ':':
+ {
+ /* We have an axis. */
+ setState(Axis);
+ return keyword ? Token(keyword->token) : id;
+ }
+ default:
+ {
+ /* It's a QName. */
+ ++m_pos; /* Consume the colon. */
+
+ const Token id2(tokenizeNCName());
+
+ if(id2.type != NCNAME)
+ {
+ --m_pos;
+ return id;
+ }
+
+ setState(Operator);
+ const int qNameLen = id.value.length() + id2.value.length() + 1;
+ return Token(QNAME, m_data.mid(m_pos - qNameLen, qNameLen));
+ }
+ }
+ }
+
+ if(!keyword || isOperatorKeyword(keyword->token))
+ {
+ setState(Operator);
+ return id;
+ }
+
+ const TokenType ws = consumeWhitespace();
+ if(ws == ERROR) // TODO this should test for success. Write test.
+ return Token(ERROR);
+
+ if(atEnd())
+ {
+ setState(Operator);
+ return id;
+ }
+
+ /* Let the if-body apply for constructors, and node type tests. */
+ if(isTypeToken(keyword->token) ||
+ keyword->token == TYPESWITCH ||
+ keyword->token == ORDERED ||
+ keyword->token == UNORDERED ||
+ keyword->token == IF)
+ {
+ switch(peekCurrent())
+ {
+ case '(':
+ {
+ // TODO See if we can remove DOCUMENT from isTypeToken.
+ if(isTypeToken(keyword->token) && keyword->token != DOCUMENT)
+ {
+ m_tokenStack.push(Token(LPAREN));
+ ++m_pos; /* Consume '('. */
+ pushState(Operator);
+
+ if(keyword->token == PROCESSING_INSTRUCTION)
+ setState(KindTestForPI);
+ else
+ setState(KindTest);
+
+ return Token(keyword->token);
+ }
+ else if(keyword->token == TYPESWITCH || keyword->token == IF)
+ return Token(keyword->token);
+ else /* It's a function call. */
+ return id;
+ }
+ case '{':
+ {
+ m_tokenStack.push(Token(CURLY_LBRACE));
+ ++m_pos; /* Consume '{'. */
+ pushState(Operator);
+ /* Stay in state Default. */
+ return Token(keyword->token);
+ }
+ default:
+ {
+ /* We have read in a token which is for instance
+ * "return", and now it can be an element
+ * test("element") a node kind test("element()"), or a
+ * computed element constructor("element name {...").
+ * We need to do a two-token lookahead here, because
+ * "element return" can be an element test followed by
+ * the return keyword, but it can also be an element
+ * constructor("element return {"). */
+ if(isNCNameStart(current()))
+ {
+ const int currentPos = m_pos;
+ const Token token2 = tokenizeNCNameOrQName();
+
+ if(token2.hasError())
+ return token2;
+
+ handleWhitespace();
+
+ if(peekCurrent() == '{')
+ {
+ /* An element constructor. */
+ m_tokenStack.push(token2);
+ return Token(keyword->token);
+ }
+
+ /* We jump back in the stream, we need to tokenize token2 according
+ * to the state. */
+ m_pos = currentPos;
+ setState(Operator);
+ return Token(NCNAME, QLatin1String(keyword->name));
+ }
+ }
+ }
+ }
+
+ if(peekCurrent() == '$')
+ {
+ setState(VarName);
+ return Token(keyword->token);
+ }
+
+ /* It's not a node type, it's not the typeswitch expression, but it is a function callsite. */
+ if(peekCurrent() == '(')
+ return id;
+ else if(peekCurrent() == '{' && keyword->token == VALIDATE)
+ return Token(keyword->token);
+
+ if(!isNCNameStart(current()))
+ {
+ setState(Operator);
+ return id;
+ }
+
+ const Token id2(tokenizeNCName());
+ const TokenMap *const keyword2 = lookupKeyword(id2.value);
+
+ if(!keyword2)
+ {
+ /* It's a syntax error. All cases of two subsequent ncnames are keywords(e.g, declarations). */
+ setState(Operator);
+ return id;
+ }
+
+ switch(keyword->token)
+ {
+ case DECLARE:
+ {
+ switch(keyword2->token)
+ {
+ case VARIABLE:
+ /* Fallthrough. */
+ case FUNCTION:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Default);
+ return Token(keyword->token);
+ }
+ case OPTION:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Default);
+ return Token(keyword->token);
+ }
+ case COPY_NAMESPACES:
+ /* Fallthrough. */
+ case ORDERING:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(NamespaceKeyword);
+ return Token(keyword->token);
+ }
+ case CONSTRUCTION:
+ {
+ // TODO identical to CONSTRUCTION?
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Operator);
+ return Token(keyword->token);
+ }
+ case NAMESPACE:
+ /* Fallthrough. */
+ case BASEURI:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(NamespaceDecl);
+ return Token(keyword->token);
+ }
+ case BOUNDARY_SPACE:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(XMLSpaceDecl);
+ return Token(keyword->token);
+ }
+ case DEFAULT:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ const TokenType ws2 = consumeWhitespace();
+ if(ws2 != SUCCESS)
+ {
+ m_tokenStack.prepend(Token(ws2));
+ return Token(keyword->token);
+ }
+
+ const Token id3(tokenizeNCName());
+
+ if(id3.type != NCNAME)
+ {
+ m_tokenStack.prepend(id3);
+ return Token(keyword->token);
+ }
+
+ const TokenMap *const keyword3 = lookupKeyword(id3.value);
+ if(!keyword3)
+ {
+ m_tokenStack.prepend(id3);
+ return Token(keyword->token);
+ }
+ else
+ {
+ m_tokenStack.prepend(Token(keyword3->token));
+
+ if(keyword3->token == ORDER)
+ setState(Operator);
+ else
+ setState(NamespaceDecl);
+ }
+
+ return Token(keyword->token);
+ }
+ default:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Default);
+ return id;
+ }
+ }
+ }
+ case XQUERY:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ if(keyword2->token == VERSION)
+ {
+ setState(NamespaceDecl);
+ return Token(keyword->token);
+ }
+ else
+ {
+ setState(Operator);
+ return id;
+ }
+ }
+ case IMPORT:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ switch(keyword2->token)
+ {
+ case SCHEMA:
+ /* Fallthrough. */
+ case MODULE:
+ {
+ setState(NamespaceKeyword);
+ return Token(keyword->token);
+ }
+ default:
+ {
+ setState(Operator);
+ return id;
+ }
+ }
+ }
+ case VALIDATE:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ switch(keyword2->token)
+ {
+ case LAX:
+ case STRICT:
+ {
+ pushState(Operator);
+ return Token(keyword->token);
+ }
+ default:
+ {
+ setState(Operator);
+ return id;
+ }
+ }
+ }
+ default:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Operator);
+ return id;
+ }
+ }
+
+ Q_ASSERT(false);
+
+ }
+ case VarName:
+ {
+ if(peekCurrent() == '$')
+ return tokenAndAdvance(DOLLAR);
+
+ setState(Operator);
+ return tokenizeNCNameOrQName();
+ Q_ASSERT(false);
+ }
+ case ItemType:
+ {
+ switch(peekCurrent())
+ {
+ case '(':
+ return tokenAndChangeState(LPAREN, KindTest);
+ case '$':
+ return tokenAndChangeState(DOLLAR, VarName);
+ }
+
+ const Token name(tokenizeNCNameOrQName());
+
+ if(name.hasError())
+ return error();
+
+ else if(name.type == QNAME)
+ {
+ setState(OccurrenceIndicator);
+ return name;
+ }
+ else
+ {
+ const TokenMap *const keyword = lookupKeyword(name.value);
+
+ if(keyword)
+ {
+ pushState(OccurrenceIndicator);
+ return Token(keyword->token);
+ }
+ else
+ {
+ setState(Default);
+ return name;
+ }
+ }
+ Q_ASSERT(false);
+ }
+ case KindTest:
+ {
+ switch(peekCurrent())
+ {
+ case ')':
+ {
+ popState();
+ return tokenAndAdvance(RPAREN);
+ }
+ case '(':
+ return tokenAndAdvance(LPAREN);
+ case ',':
+ return tokenAndAdvance(COMMA);
+ case '*':
+ return tokenAndAdvance(STAR);
+ case '?':
+ return tokenAndAdvance(QUESTION);
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ return tokenizeStringLiteral();
+ }
+
+ const Token nc(tokenizeNCNameOrQName());
+ if(nc.hasError())
+ return nc;
+
+ const TokenType ws = consumeWhitespace();
+ if(ws == ERROR)
+ return error();
+
+ if(peekCurrent() == '(')
+ {
+ const TokenMap *const keyword = lookupKeyword(nc.value);
+ if(keyword)
+ {
+ pushState(KindTest);
+ return Token(keyword->token);
+ }
+ else
+ return nc;
+ }
+ else
+ return nc;
+ Q_ASSERT(false);
+ }
+ case KindTestForPI:
+ {
+ switch(peekCurrent())
+ {
+ case ')':
+ {
+ popState();
+ return tokenAndAdvance(RPAREN);
+ }
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ return tokenizeStringLiteral();
+ default:
+ return tokenizeNCName();
+ }
+ Q_ASSERT(false);
+ }
+ case OccurrenceIndicator:
+ {
+ switch(peekCurrent())
+ {
+ case '?':
+ return tokenAndChangeState(QUESTION, Operator);
+ case '*':
+ return tokenAndChangeState(STAR, Operator);
+ case '+':
+ return tokenAndChangeState(PLUS, Operator);
+ default:
+ {
+ setState(Operator);
+ return nextToken();
+ }
+ }
+ Q_ASSERT(false);
+ }
+ case XQueryVersion:
+ {
+ switch(peekCurrent())
+ {
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ return tokenizeStringLiteral();
+ case ';':
+ return tokenAndChangeState(SEMI_COLON, Default);
+ }
+
+ const Token id(tokenizeNCName());
+
+ if(id.type != NCNAME)
+ return id;
+
+ const TokenMap *const keyword = lookupKeyword(id.value);
+ if(keyword)
+ return tokenAndChangeState(keyword->token, Default);
+ else
+ return id;
+ Q_ASSERT(false);
+ }
+ case StartTag:
+ {
+ if(peekAhead(-1) == '<')
+ {
+ if(current().isSpace())
+ return Token(ERROR);
+ }
+ else
+ {
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+ }
+
+ switch(peekCurrent())
+ {
+ case '/':
+ {
+ if(peekAhead() == '>')
+ {
+ m_pos += 2;
+
+ if(m_scanOnly)
+ return Token(POSITION_SET);
+ else
+ {
+ popState();
+ return Token(QUICK_TAG_END);
+ }
+ }
+ else
+ return error();
+ }
+ case '>':
+ {
+ if(m_scanOnly)
+ return tokenAndChangeState(POSITION_SET, StartTag);
+ else
+ return tokenAndChangeState(G_GT, ElementContent);
+ }
+ case '=':
+ return tokenAndAdvance(G_EQ);
+ case '\'':
+ return tokenAndChangeState(APOS, AposAttributeContent);
+ case '"':
+ return tokenAndChangeState(QUOTE, QuotAttributeContent);
+ default:
+ return tokenizeNCNameOrQName();
+ }
+ Q_ASSERT(false);
+ }
+ case AposAttributeContent:
+ /* Fallthrough. */
+ case QuotAttributeContent:
+ {
+ const QChar sep(state() == AposAttributeContent ? QLatin1Char('\'') : QLatin1Char('"'));
+ QString result;
+ result.reserve(20);
+
+ if(m_scanOnly)
+ {
+ int stack = 0;
+ return attributeAsRaw(sep, stack, m_pos, true, result);
+ }
+
+ Q_ASSERT(!m_scanOnly);
+ while(true)
+ {
+ if(atEnd())
+ {
+ /* In the case that the XSL-T tokenizer invokes us with
+ * default state QuotAttributeContent, we need to be able
+ * to return a single string, in case that is all we have
+ * accumulated. */
+ if(result.isEmpty())
+ return Token(END_OF_FILE);
+ else
+ return Token(STRING_LITERAL, result);
+ }
+
+ const QChar curr(current());
+
+ if(curr == sep)
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+
+ if(m_data.at(m_pos + 1) == sep)
+ {
+ /* The quoting mechanism was used. */
+ m_pos += 2;
+ result.append(sep);
+ continue;
+ }
+
+ const QChar next(m_data.at(m_pos + 1));
+ if(!next.isSpace() && next != QLatin1Char('/') && next != QLatin1Char('>'))
+ return Token(ERROR); // i18n Space must separate attributes
+ else if(result.isEmpty())
+ {
+ return tokenAndChangeState(state() == AposAttributeContent ? APOS : QUOTE,
+ StartTag, 1);
+ }
+ else
+ {
+ /* Don't consume the sep, but leave it so we next time return a token for it. */
+ return Token(STRING_LITERAL, result);
+ }
+
+ ++m_pos;
+ continue;
+ }
+ else if(curr == QLatin1Char('{'))
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '{')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('{'));
+ }
+ else
+ {
+ if(result.isEmpty())
+ {
+ /* The Attribute Value Template appeared directly in the attribute. */
+ pushState();
+ return tokenAndChangeState(CURLY_LBRACE, Default);
+ }
+ else
+ {
+ /* We don't advance, keep '{' as next token. */
+ return Token(STRING_LITERAL, result);
+ }
+ }
+ }
+ else if(curr == QLatin1Char('}'))
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '}')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('}'));
+ }
+ else
+ return Token(ERROR);
+ }
+ else if(curr == QLatin1Char('&'))
+ {
+ const QString ret(tokenizeCharacterReference());
+ if(ret.isNull())
+ return Token(ERROR);
+ else
+ result.append(ret);
+ }
+ else if(curr == QLatin1Char('<'))
+ return Token(STRING_LITERAL, result);
+ else
+ {
+ /* See Extensible Markup Language (XML) 1.0 (Fourth Edition),
+ * 3.3.3 Attribute-Value Normalization.
+ *
+ * However, it is complicated a bit by that AVN is defined on top of
+ * EOL normalization and we do those two in one go here. */
+ switch(curr.unicode())
+ {
+ case 0xD:
+ {
+ if(peekAhead() == '\n')
+ {
+ result.append(QLatin1Char(' '));
+ ++m_pos;
+ break;
+ }
+ }
+ case 0xA:
+ /* Fallthrough. */
+ case 0x9:
+ {
+ result.append(QLatin1Char(' '));
+ break;
+ }
+ default:
+ result.append(curr);
+ }
+ }
+
+ ++m_pos;
+ }
+ Q_ASSERT(false);
+ }
+ case ElementContent:
+ {
+ QString result;
+ result.reserve(20);
+
+ /* Whether the text node, result, may be whitespace only. Character references
+ * and CDATA sections disables that. */
+ bool mayBeWS = true;
+
+ CharacterSkips skipEOLNormalization;
+
+ while(true)
+ {
+ if(atEnd())
+ return Token(END_OF_FILE);
+
+ switch(peekCurrent())
+ {
+ case '<':
+ {
+ if(!result.isEmpty() && peekAhead(2) != '[')
+ {
+ /* We encountered the end, and it was not a CDATA section. */
+ /* We don't advance. Next time we'll handle the <... stuff. */
+ return Token(mayBeWS ? STRING_LITERAL : NON_BOUNDARY_WS, normalizeEOL(result, skipEOLNormalization));
+ }
+
+ ++m_pos;
+ if(atEnd())
+ return Token(END_OF_FILE);
+
+ const QChar ahead(current());
+ if(ahead.isSpace())
+ return error();
+ else if(ahead == QLatin1Char('/'))
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(m_data.at(m_pos + 1).isSpace())
+ return error();
+ else
+ return tokenAndChangeState(BEGIN_END_TAG, EndTag);
+ }
+ else if(isNCNameStart(ahead))
+ {
+ pushState();
+ return tokenAndChangeState(G_LT, StartTag, 0);
+ }
+ else if(aheadEquals("!--", 3, 0))
+ {
+ pushState();
+ m_pos += 3;
+ return tokenAndChangeState(COMMENT_START, XMLComment, 0);
+ }
+ else if(aheadEquals("![CDATA[", 8, 0))
+ {
+ mayBeWS = false;
+ m_pos += 8;
+ const int start = m_pos;
+ const int len = scanUntil("]]>");
+
+ if(len == -1)
+ return Token(END_OF_FILE);
+
+ m_pos += 2; /* Consume "]]>". Note that m_pos is on '!'. */
+ result.append(m_data.mid(start, len));
+ break;
+ }
+ else if(ahead == QLatin1Char('?'))
+ {
+ pushState();
+ return tokenAndChangeState(PI_START, ProcessingInstructionName);
+ }
+ else
+ return Token(G_LT);
+ }
+ case '&':
+ {
+ const QString ret(tokenizeCharacterReference());
+ if(ret.isNull())
+ return Token(ERROR);
+ else
+ {
+ skipEOLNormalization.insert(result.count());
+ result.append(ret);
+ mayBeWS = false;
+ break;
+ }
+ }
+ case '{':
+ {
+ // TODO remove this check, also below.
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '{')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('{'));
+ }
+ else
+ {
+ if(result.isEmpty())
+ {
+ pushState();
+ return tokenAndChangeState(CURLY_LBRACE, Default);
+ }
+ else
+ {
+ /* We don't advance here. */
+ return Token(mayBeWS ? STRING_LITERAL : NON_BOUNDARY_WS, normalizeEOL(result, skipEOLNormalization));
+ }
+ }
+ break;
+ }
+ case '}':
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '}')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('}'));
+ }
+ else
+ {
+ /* This is a parse error, and the grammar won't be able
+ * to reduce this CURLY_RBRACE. */
+ return tokenAndChangeState(CURLY_RBRACE, Default);
+ }
+ break;
+ }
+ case '\n':
+ {
+ /* We want to translate \r\n into \n. */
+ if(peekAhead(-1) == '\r')
+ break;
+ /* else, fallthrough. */
+ }
+ case '\r':
+ {
+ result.append(QLatin1Char('\n'));
+ break;
+ }
+ default:
+ {
+ result.append(current());
+ break;
+ }
+ }
+ ++m_pos;
+ }
+ Q_ASSERT(false);
+ }
+ case ProcessingInstructionName:
+ {
+ const int start = m_pos;
+
+ while(true)
+ {
+ ++m_pos;
+ if(m_pos >= m_length)
+ return Token(END_OF_FILE);
+
+ const QChar next(current());
+ if(next.isSpace() || next == QLatin1Char('?'))
+ {
+ return tokenAndChangeState(PI_TARGET, m_data.mid(start, m_pos - start),
+ ProcessingInstructionContent);
+ }
+ }
+ Q_ASSERT(false);
+ }
+ case ProcessingInstructionContent:
+ {
+ /* Consume whitespace between the name and the content. */
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+
+ const int start = m_pos;
+ const int len = scanUntil("?>");
+
+ if(len == -1)
+ return Token(END_OF_FILE);
+ else
+ {
+ m_pos += 2; /* Consume "?>" */
+ popState();
+ return Token(PI_CONTENT, normalizeEOL(m_data.mid(start, len), CharacterSkips()));
+ }
+ Q_ASSERT(false);
+ }
+ case EndTag:
+ {
+ if(consumeRawWhitespace())
+ return END_OF_FILE;
+
+ if(peekCurrent() == '>')
+ {
+ popState();
+ return tokenAndAdvance(G_GT);
+ }
+ else
+ return tokenizeNCNameOrQName();
+ Q_ASSERT(false);
+ }
+ case XMLComment:
+ {
+ const int start = m_pos;
+ const int len = scanUntil("--");
+
+ if(len == -1)
+ return END_OF_FILE;
+ else
+ {
+ m_pos += 2; /* Consume "--". */
+ popState();
+
+ if(peekCurrent() == '>')
+ {
+ ++m_pos;
+ return Token(COMMENT_CONTENT, normalizeEOL(m_data.mid(start, len), CharacterSkips()));
+ }
+ else
+ return error();
+ }
+ Q_ASSERT(false);
+ }
+ case Pragma:
+ {
+ /* Consume whitespace. */
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+
+ setState(PragmaContent);
+ return tokenizeNCNameOrQName();
+ }
+ case PragmaContent:
+ {
+ QString result;
+ result.reserve(20);
+
+ const bool hasWS = m_pos < m_length && current().isSpace();
+
+ /* Consume all whitespace up to the pragma content(if any). */
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+
+ if(peekCurrent() == '#' && peekAhead() == ')')
+ {
+ /* We reached the end, and there's no pragma content. */
+ return tokenAndChangeState(PRAGMA_END, Default, 2);
+ }
+ else if(!hasWS)
+ {
+ /* A separating space is required if there's pragma content. */
+ return error(); /* i18n */
+ }
+
+ const int start = m_pos;
+ const int len = scanUntil("#)");
+ if(len == -1)
+ return Token(END_OF_FILE);
+
+ return Token(STRING_LITERAL, m_data.mid(start, len));
+ Q_ASSERT(false);
+ }
+ }
+
+ Q_ASSERT(false);
+ return error();
+}
+
+Tokenizer::Token XQueryTokenizer::attributeAsRaw(const QChar sep,
+ int &sepStack,
+ const int startPos,
+ const bool aInLiteral,
+ QString &result)
+{
+ bool inLiteral = aInLiteral;
+ const char otherSep = (sep == QLatin1Char('"') ? '\'' : '"');
+
+ while(true)
+ {
+ if(atEnd())
+ return END_OF_FILE;
+
+ if(peekCurrent() == sep.unicode())
+ {
+ if(inLiteral)
+ inLiteral = false;
+ else
+ inLiteral = true;
+
+ if(peekAhead() == sep.unicode())
+ {
+ /* The quoting mechanism was used. */
+ result.append(current());
+ m_pos += 2;
+ continue;
+ }
+ else
+ {
+ /* Don't consume the separator, such that we
+ * return a token for it next time. */
+ if(m_pos == startPos)
+ {
+ ++m_pos;
+ setState(StartTag);
+ return Token(sep == QLatin1Char('"') ? QUOTE : APOS);
+ }
+
+
+ if(sepStack == 0)
+ {
+ return Token(STRING_LITERAL, result);
+ }
+ else
+ {
+ result.append(current());
+ ++m_pos;
+ continue;
+ }
+ }
+ }
+ else if(peekCurrent() == '&')
+ {
+ const QString ret(tokenizeCharacterReference());
+ if(ret.isNull())
+ return Token(ERROR);
+ else
+ {
+ result.append(ret);
+ ++m_pos;
+ continue;
+ }
+ }
+ else if(peekCurrent() == otherSep)
+ {
+ result.append(current());
+ ++m_pos;
+
+ if(peekCurrent() == otherSep)
+ ++m_pos;
+
+ if(inLiteral)
+ inLiteral = false;
+ else
+ inLiteral = true;
+
+ continue;
+ }
+ else if(peekCurrent() == '{')
+ {
+ result.append(current());
+
+ if(peekAhead() == '{')
+ {
+ m_pos += 2;
+ continue;
+ }
+ else
+ {
+ ++m_pos;
+ ++sepStack;
+ const Token t(attributeAsRaw(sep, sepStack, startPos, false, result));
+ if(t.type != SUCCESS)
+ return t;
+ }
+
+ }
+ else if(peekCurrent() == '}')
+ {
+ if(inLiteral && peekAhead() == '}')
+ {
+ result.append(current());
+ m_pos += 2;
+ continue;
+ }
+ else
+ {
+ ++m_pos;
+ --sepStack;
+ return Token(SUCCESS); /* The return value is arbitrary. */
+ }
+ }
+ else
+ {
+ result.append(current());
+ ++m_pos;
+ }
+ }
+}
+
+Tokenizer::Token XQueryTokenizer::nextToken(YYLTYPE *const sourceLocator)
+{
+ sourceLocator->first_line = m_line;
+ sourceLocator->first_column = m_pos - m_columnOffset + 1; /* Plus 1, since m_pos is 0-based. */
+
+ if(m_tokenStack.isEmpty())
+ return nextToken();
+ else
+ {
+ const Token retval(m_tokenStack.pop());
+
+ switch(retval.type)
+ {
+ case MODULE:
+ /* Fallthrough.*/
+ case SCHEMA:
+ /* Fallthrough.*/
+ case COPY_NAMESPACES:
+ {
+ setState(NamespaceKeyword);
+ break;
+ }
+ case VERSION:
+ {
+ setState(XQueryVersion);
+ break;
+ }
+ case AS:
+ /* Fallthrough. */
+ case OF:
+ {
+ setState(ItemType);
+ break;
+ }
+ default:
+ {
+ if(isOperatorKeyword(retval.type))
+ setState(Default);
+
+ break;
+ }
+ };
+
+ return retval;
+ }
+}
+
+int XQueryTokenizer::commenceScanOnly()
+{
+ m_scanOnly = true;
+ return m_pos;
+}
+
+void XQueryTokenizer::resumeTokenizationFrom(const int pos)
+{
+ m_scanOnly = false;
+ m_pos = pos;
+}
+
+void XQueryTokenizer::setParserContext(const ParserContext::Ptr &)
+{
+}
+
+#undef handleWhitespace
+
+} // namespace QPatternist
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/qxquerytokenizer_p.h b/src/xmlpatterns/parser/qxquerytokenizer_p.h
new file mode 100644
index 0000000..36611ef
--- /dev/null
+++ b/src/xmlpatterns/parser/qxquerytokenizer_p.h
@@ -0,0 +1,332 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XQueryTokenizer_H
+#define Patternist_XQueryTokenizer_H
+
+#include <QHash>
+#include <QSet>
+#include <QStack>
+#include <QString>
+#include <QUrl>
+
+#include "qtokenizer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ struct TokenMap;
+
+ /**
+ * @short A hand-written tokenizer which tokenizes XQuery 1.0 & XPath 2.0,
+ * and delivers tokens to the Bison generated parser.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class XQueryTokenizer : public Tokenizer
+ {
+ public:
+ /**
+ * Tokenizer states. Organized alphabetically.
+ */
+ enum State
+ {
+ AfterAxisSeparator,
+ AposAttributeContent,
+ Axis,
+ Default,
+ ElementContent,
+ EndTag,
+ ItemType,
+ KindTest,
+ KindTestForPI,
+ NamespaceDecl,
+ NamespaceKeyword,
+ OccurrenceIndicator,
+ Operator,
+ Pragma,
+ PragmaContent,
+ ProcessingInstructionContent,
+ ProcessingInstructionName,
+ QuotAttributeContent,
+ StartTag,
+ VarName,
+ XMLComment,
+ XMLSpaceDecl,
+ XQueryVersion
+ };
+
+ XQueryTokenizer(const QString &query,
+ const QUrl &location,
+ const State startingState = Default);
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator);
+ virtual int commenceScanOnly();
+ virtual void resumeTokenizationFrom(const int position);
+
+ /**
+ * Does nothing.
+ */
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo);
+
+ private:
+
+ /**
+ * Returns the character corresponding to the builtin reference @p
+ * reference. For instance, passing @c gt will give you '>' in return.
+ *
+ * If @p reference is an invalid character reference, a null QChar is
+ * returned.
+ *
+ * @see QChar::isNull()
+ */
+ QChar charForReference(const QString &reference);
+
+ inline Token tokenAndChangeState(const TokenType code,
+ const State state,
+ const int advance = 1);
+ inline Token tokenAndChangeState(const TokenType code,
+ const QString &value,
+ const State state);
+ inline Token tokenAndAdvance(const TokenType code,
+ const int advance = 1);
+ QString tokenizeCharacterReference();
+
+ inline Token tokenizeStringLiteral();
+ inline Token tokenizeNumberLiteral();
+
+ /**
+ * @returns the character @p length characters from the current
+ * position.
+ */
+ inline char peekAhead(const int length = 1) const;
+
+ /**
+ * @returns whether the stream, starting from @p offset from the
+ * current position, matches @p chs. The length of @p chs is @p len.
+ */
+ inline bool aheadEquals(const char *const chs,
+ const int len,
+ const int offset = 1) const;
+
+ inline Token tokenizeNCName();
+ static inline bool isOperatorKeyword(const TokenType);
+
+ static inline bool isDigit(const char ch);
+ static inline Token error();
+ inline TokenType consumeWhitespace();
+
+ /**
+ * @short Returns the character at the current position, converted to
+ * @c ASCII.
+ *
+ * Equivalent to calling:
+ *
+ * @code
+ * current().toAscii();
+ * @endcode
+ */
+ inline char peekCurrent() const;
+
+ /**
+ * Disregarding encoding conversion, equivalent to calling:
+ *
+ * @code
+ * peekAhead(0);
+ * @endcode
+ */
+ inline const QChar current() const;
+
+ /**
+ * @p hadWhitespace is always set to a proper value.
+ *
+ * @returns the length of whitespace scanned before reaching "::", or
+ * -1 if something else was found.
+ */
+ int peekForColonColon() const;
+
+ static inline bool isNCNameStart(const QChar ch);
+ static inline bool isNCNameBody(const QChar ch);
+ static inline const TokenMap *lookupKeyword(const QString &keyword);
+ inline void popState();
+ inline void pushState(const State state);
+ inline State state() const;
+ inline void setState(const State s);
+ static bool isTypeToken(const TokenType t);
+
+ inline Token tokenizeNCNameOrQName();
+ /**
+ * Advances m_pos until content is encountered.
+ *
+ * Returned is the length stretching from m_pos when starting, until
+ * @p content is encountered. @p content is not included in the length.
+ */
+ int scanUntil(const char *const content);
+
+ /**
+ * Same as calling:
+ * @code
+ * pushState(currentState());
+ * @endcode
+ */
+ inline void pushState();
+
+ /**
+ * Consumes only whitespace, in the traditional sense. The function exits
+ * if non-whitespace is encountered, such as the start of a comment.
+ *
+ * @returns @c true if the end was reached, otherwise @c false
+ */
+ inline bool consumeRawWhitespace();
+
+ /**
+ * @short Parses comments: <tt>(: comment content :)</tt>. It recurses for
+ * parsing nested comments.
+ *
+ * It is assumed that the start token for the comment, "(:", has
+ * already been parsed.
+ *
+ * Typically, don't call this function, but ignoreWhitespace().
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#comments">XML Path Language (XPath)
+ * 2.0, 2.6 Comments</a>
+ * @returns
+ * - SUCCESS if everything went ok
+ * - ERROR if there was an error in parsing one or more comments
+ * - END_OF_FILE if the end was reached
+ */
+ Tokenizer::TokenType consumeComment();
+
+ /**
+ * Determines whether @p code is a keyword
+ * that is followed by a second keyword. For instance <tt>declare
+ * function</tt>.
+ */
+ static inline bool isPhraseKeyword(const TokenType code);
+
+ /**
+ * A set of indexes into a QString, the one being passed to
+ * normalizeEOL() whose characters shouldn't be normalized. */
+ typedef QSet<int> CharacterSkips;
+
+ /**
+ * Returns @p input, normalized according to
+ * <a href="http://www.w3.org/TR/xquery/#id-eol-handling">XQuery 1.0:
+ * An XML Query Language, A.2.3 End-of-Line Handling</a>
+ */
+ static QString normalizeEOL(const QString &input,
+ const CharacterSkips &characterSkips);
+
+ inline bool atEnd() const
+ {
+ return m_pos == m_length;
+ }
+
+ Token nextToken();
+ /**
+ * Instead of recognizing and tokenizing embedded expressions in
+ * direct attriute constructors, this function is essentially a mini
+ * recursive-descent parser that has the necessary logic to recognize
+ * embedded expressions and their potentially interfering string literals, in
+ * order to scan to the very end of the attribute value, and return the
+ * whole as a string.
+ *
+ * There is of course syntax errors this function will not detect, but
+ * that is ok since the attributes will be parsed once more.
+ *
+ * An inelegant solution, but which gets the job done.
+ *
+ * @see commenceScanOnly(), resumeTokenizationFrom()
+ */
+ Token attributeAsRaw(const QChar separator,
+ int &stack,
+ const int startPos,
+ const bool inLiteral,
+ QString &result);
+
+ const QString m_data;
+ const int m_length;
+ State m_state;
+ QStack<State> m_stateStack;
+ int m_pos;
+
+ /**
+ * The current line number.
+ *
+ * The line number and column number both starts at 1.
+ */
+ int m_line;
+
+ /**
+ * The offset into m_length for where
+ * the current column starts. So m_length - m_columnOffset
+ * is the current column.
+ *
+ * The line number and column number both starts at 1.
+ */
+ int m_columnOffset;
+
+ const NamePool::Ptr m_namePool;
+ QStack<Token> m_tokenStack;
+ QHash<QString, QChar> m_charRefs;
+ bool m_scanOnly;
+
+ Q_DISABLE_COPY(XQueryTokenizer)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/qxslttokenizer.cpp b/src/xmlpatterns/parser/qxslttokenizer.cpp
new file mode 100644
index 0000000..81498ce
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenizer.cpp
@@ -0,0 +1,2717 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qquerytransformparser_p.h"
+#include "qxquerytokenizer_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qxslttokenizer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Tokenizer::Token SingleTokenContainer::nextToken(YYLTYPE *const location)
+{
+ if(m_hasDelivered)
+ return Tokenizer::Token(END_OF_FILE);
+ else
+ {
+ *location = m_location;
+ m_hasDelivered = true;
+ return m_token;
+ }
+}
+
+XSLTTokenizer::XSLTTokenizer(QIODevice *const queryDevice,
+ const QUrl &location,
+ const ReportContext::Ptr &context,
+ const NamePool::Ptr &np) : Tokenizer(location)
+ , MaintainingReader<XSLTTokenLookup>(createElementDescriptions(), createStandardAttributes(), context, queryDevice)
+ , m_location(location)
+ , m_namePool(np)
+ /* We initialize after all name constants. */
+ , m_validationAlternatives(createValidationAlternatives())
+ , m_parseInfo(0)
+{
+ Q_ASSERT(m_namePool);
+
+ pushState(OutsideDocumentElement);
+}
+
+bool XSLTTokenizer::isAnyAttributeAllowed() const
+{
+ return m_processingMode.top() == ForwardCompatible;
+}
+
+void XSLTTokenizer::setParserContext(const ParserContext::Ptr &parseInfo)
+{
+ m_parseInfo = parseInfo;
+}
+
+void XSLTTokenizer::validateElement() const
+{
+ MaintainingReader<XSLTTokenLookup>::validateElement(currentElementName());
+}
+
+QSet<XSLTTokenizer::NodeName> XSLTTokenizer::createStandardAttributes()
+{
+ QSet<NodeName> retval;
+ enum
+ {
+ ReservedForAttributes = 6
+ };
+
+ retval.reserve(6);
+
+ retval.insert(DefaultCollation);
+ retval.insert(ExcludeResultPrefixes);
+ retval.insert(ExtensionElementPrefixes);
+ retval.insert(UseWhen);
+ retval.insert(Version);
+ retval.insert(XpathDefaultNamespace);
+
+ Q_ASSERT(retval.count() == ReservedForAttributes);
+
+ return retval;
+}
+
+ElementDescription<XSLTTokenLookup>::Hash XSLTTokenizer::createElementDescriptions()
+{
+ ElementDescription<XSLTTokenLookup>::Hash result;
+ enum
+ {
+ ReservedForElements = 40
+ };
+ result.reserve(ReservedForElements);
+
+ /* xsl:apply-templates */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ApplyTemplates];
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Mode);
+ }
+
+ /* xsl:template */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Template];
+ e.optionalAttributes.insert(Match);
+ e.optionalAttributes.insert(Name);
+ e.optionalAttributes.insert(Mode);
+ e.optionalAttributes.insert(Priority);
+ e.optionalAttributes.insert(As);
+ }
+
+ /* xsl:text, xsl:choose and xsl:otherwise */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Text];
+ result.insert(Choose, e);
+ result.insert(Otherwise, e);
+ }
+
+ /* xsl:stylesheet */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Stylesheet];
+
+ e.requiredAttributes.insert(Version);
+
+ e.optionalAttributes.insert(Id);
+ e.optionalAttributes.insert(ExtensionElementPrefixes);
+ e.optionalAttributes.insert(ExcludeResultPrefixes);
+ e.optionalAttributes.insert(XpathDefaultNamespace);
+ e.optionalAttributes.insert(DefaultValidation);
+ e.optionalAttributes.insert(DefaultCollation);
+ e.optionalAttributes.insert(InputTypeAnnotations);
+ }
+
+ /* xsl:transform */
+ {
+ result[Transform] = result[Stylesheet];
+ }
+
+ /* xsl:value-of */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ValueOf];
+ e.optionalAttributes.insert(Separator);
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:variable */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Variable];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(As);
+ }
+
+ /* xsl:when & xsl:if */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[When];
+
+ e.requiredAttributes.insert(Test);
+
+ result.insert(If, e);
+ }
+
+ /* xsl:sequence, xsl:for-each */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Sequence];
+
+ e.requiredAttributes.insert(Select);
+
+ result.insert(ForEach, e);
+ }
+
+ /* xsl:comment */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[XSLTTokenLookup::Comment];
+
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:processing-instruction */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[XSLTTokenLookup::ProcessingInstruction];
+
+ e.requiredAttributes.insert(Name);
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:document */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Document];
+
+ e.optionalAttributes.insert(Validation);
+ e.optionalAttributes.insert(Type);
+ }
+
+ /* xsl:element */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Element];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Namespace);
+ e.optionalAttributes.insert(InheritNamespaces);
+ e.optionalAttributes.insert(UseAttributeSets);
+ e.optionalAttributes.insert(Validation);
+ e.optionalAttributes.insert(Type);
+ }
+
+ /* xsl:attribute */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Attribute];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Namespace);
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Separator);
+ e.optionalAttributes.insert(Validation);
+ e.optionalAttributes.insert(Type);
+ }
+
+ /* xsl:function */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Function];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(As);
+ e.optionalAttributes.insert(Override);
+ }
+
+ /* xsl:param */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Param];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(As);
+ e.optionalAttributes.insert(Required);
+ e.optionalAttributes.insert(Tunnel);
+ }
+
+ /* xsl:namespace */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Namespace];
+
+ e.requiredAttributes.insert(Name);
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:call-template */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[CallTemplate];
+ e.requiredAttributes.insert(Name);
+ }
+
+ /* xsl:perform-sort */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[PerformSort];
+ e.requiredAttributes.insert(Select);
+ }
+
+ /* xsl:sort */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Sort];
+
+ e.optionalAttributes.reserve(7);
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Lang);
+ e.optionalAttributes.insert(Order);
+ e.optionalAttributes.insert(Collation);
+ e.optionalAttributes.insert(Stable);
+ e.optionalAttributes.insert(CaseOrder);
+ e.optionalAttributes.insert(DataType);
+ }
+
+ /* xsl:import-schema */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ImportSchema];
+
+ e.optionalAttributes.reserve(2);
+ e.optionalAttributes.insert(Namespace);
+ e.optionalAttributes.insert(SchemaLocation);
+ }
+
+ /* xsl:message */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Message];
+
+ e.optionalAttributes.reserve(2);
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Terminate);
+ }
+
+ /* xsl:copy-of */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[CopyOf];
+
+ e.requiredAttributes.insert(Select);
+
+ e.optionalAttributes.reserve(2);
+ e.optionalAttributes.insert(CopyNamespaces);
+ e.optionalAttributes.insert(Type);
+ e.optionalAttributes.insert(Validation);
+ }
+
+ /* xsl:copy */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Copy];
+
+ e.optionalAttributes.reserve(5);
+ e.optionalAttributes.insert(CopyNamespaces);
+ e.optionalAttributes.insert(InheritNamespaces);
+ e.optionalAttributes.insert(UseAttributeSets);
+ e.optionalAttributes.insert(Type);
+ e.optionalAttributes.insert(Validation);
+ }
+
+ /* xsl:output */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Output];
+
+ e.optionalAttributes.reserve(17);
+ e.optionalAttributes.insert(Name);
+ e.optionalAttributes.insert(Method);
+ e.optionalAttributes.insert(ByteOrderMark);
+ e.optionalAttributes.insert(CdataSectionElements);
+ e.optionalAttributes.insert(DoctypePublic);
+ e.optionalAttributes.insert(DoctypeSystem);
+ e.optionalAttributes.insert(Encoding);
+ e.optionalAttributes.insert(EscapeUriAttributes);
+ e.optionalAttributes.insert(IncludeContentType);
+ e.optionalAttributes.insert(Indent);
+ e.optionalAttributes.insert(MediaType);
+ e.optionalAttributes.insert(NormalizationForm);
+ e.optionalAttributes.insert(OmitXmlDeclaration);
+ e.optionalAttributes.insert(Standalone);
+ e.optionalAttributes.insert(UndeclarePrefixes);
+ e.optionalAttributes.insert(UseCharacterMaps);
+ e.optionalAttributes.insert(Version);
+ }
+
+ /* xsl:attribute-set */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[AttributeSet];
+
+ e.requiredAttributes.insert(Name);
+ e.optionalAttributes.insert(UseAttributeSets);
+ }
+
+ /* xsl:include and xsl:import. */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Include];
+ e.requiredAttributes.insert(Href);
+ result[Import] = e;
+ }
+
+ /* xsl:with-param */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[WithParam];
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(As);
+ e.optionalAttributes.insert(Tunnel);
+ }
+
+ /* xsl:strip-space */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[StripSpace];
+ e.requiredAttributes.insert(Elements);
+
+ result.insert(PreserveSpace, e);
+ }
+
+ /* xsl:result-document */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ResultDocument];
+
+ e.optionalAttributes.insert(ByteOrderMark);
+ e.optionalAttributes.insert(CdataSectionElements);
+ e.optionalAttributes.insert(DoctypePublic);
+ e.optionalAttributes.insert(DoctypeSystem);
+ e.optionalAttributes.insert(Encoding);
+ e.optionalAttributes.insert(EscapeUriAttributes);
+ e.optionalAttributes.insert(Format);
+ e.optionalAttributes.insert(Href);
+ e.optionalAttributes.insert(IncludeContentType);
+ e.optionalAttributes.insert(Indent);
+ e.optionalAttributes.insert(MediaType);
+ e.optionalAttributes.insert(Method);
+ e.optionalAttributes.insert(NormalizationForm);
+ e.optionalAttributes.insert(OmitXmlDeclaration);
+ e.optionalAttributes.insert(OutputVersion);
+ e.optionalAttributes.insert(Standalone);
+ e.optionalAttributes.insert(Type);
+ e.optionalAttributes.insert(UndeclarePrefixes);
+ e.optionalAttributes.insert(UseCharacterMaps);
+ e.optionalAttributes.insert(Validation);
+ }
+
+ /* xsl:key */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Key];
+
+ e.requiredAttributes.insert(Name);
+ e.requiredAttributes.insert(Match);
+
+ e.optionalAttributes.insert(Use);
+ e.optionalAttributes.insert(Collation);
+ }
+
+ /* xsl:analyze-string */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[AnalyzeString];
+
+ e.requiredAttributes.insert(Select);
+ e.requiredAttributes.insert(Regex);
+
+ e.optionalAttributes.insert(Flags);
+ }
+
+ /* xsl:matching-substring */
+ {
+ /* We insert a default constructed value. */
+ result[MatchingSubstring];
+ }
+
+ /* xsl:non-matching-substring */
+ {
+ /* We insert a default constructed value. */
+ result[NonMatchingSubstring];
+ }
+
+ Q_ASSERT(result.count() == ReservedForElements);
+
+ return result;
+}
+
+QHash<QString, int> XSLTTokenizer::createValidationAlternatives()
+{
+ QHash<QString, int> retval;
+
+ retval.insert(QLatin1String("preserve"), 0);
+ retval.insert(QLatin1String("strip"), 1);
+ retval.insert(QLatin1String("strict"), 2);
+ retval.insert(QLatin1String("lax"), 3);
+
+ return retval;
+}
+
+bool XSLTTokenizer::whitespaceToSkip() const
+{
+ return m_stripWhitespace.top() && isWhitespace();
+}
+
+void XSLTTokenizer::unexpectedContent(const ReportContext::ErrorCode code) const
+{
+ QString message;
+
+ ReportContext::ErrorCode effectiveCode = code;
+
+ switch(tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT())
+ {
+ switch(currentElementName())
+ {
+ case Include:
+ effectiveCode = ReportContext::XTSE0170;
+ break;
+ case Import:
+ effectiveCode = ReportContext::XTSE0190;
+ break;
+ default:
+ ;
+ }
+ }
+
+ message = QtXmlPatterns::tr("Element %1 is not allowed at this location.")
+ .arg(formatKeyword(name()));
+ break;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ return;
+
+ message = QtXmlPatterns::tr("Text nodes are not allowed at this location.");
+ break;
+ }
+ case QXmlStreamReader::Invalid:
+ {
+ /* It's an issue with well-formedness. */
+ message = escape(errorString());
+ break;
+ }
+ default:
+ Q_ASSERT(false);
+ }
+
+ error(message, effectiveCode);
+}
+
+void XSLTTokenizer::checkForParseError() const
+{
+ if(hasError())
+ {
+ error(QtXmlPatterns::tr("Parse error: %1").arg(escape(errorString())), ReportContext::XTSE0010);
+ }
+}
+
+QString XSLTTokenizer::readElementText()
+{
+ QString result;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::Characters:
+ {
+ result += text().toString();
+ continue;
+ }
+ case QXmlStreamReader::Comment:
+ /* Fallthrough. */
+ case QXmlStreamReader::ProcessingInstruction:
+ continue;
+ case QXmlStreamReader::EndElement:
+ return result;
+ default:
+ unexpectedContent();
+ }
+ }
+
+ checkForParseError();
+ return result;
+}
+
+int XSLTTokenizer::commenceScanOnly()
+{
+ /* Do nothing, return a dummy value. */
+ return 0;
+}
+
+void XSLTTokenizer::resumeTokenizationFrom(const int position)
+{
+ /* Do nothing. */
+ Q_UNUSED(position);
+}
+
+void XSLTTokenizer::handleXSLTVersion(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isXSLTElement,
+ const QXmlStreamAttributes *atts,
+ const bool generateCode,
+ const bool setGlobalVersion)
+{
+ const QString ns(isXSLTElement ? QString() : CommonNamespaces::XSLT);
+ const QXmlStreamAttributes effectiveAtts(atts ? *atts : attributes());
+
+ if(!effectiveAtts.hasAttribute(ns, QLatin1String("version")))
+ return;
+
+ const QString attribute(effectiveAtts.value(ns, QLatin1String("version")).toString());
+ const AtomicValue::Ptr number(Decimal::fromLexical(attribute));
+
+ if(number->hasError())
+ {
+ error(QtXmlPatterns::tr("The value of the XSL-T version attribute "
+ "must be a value of type %1, which %2 isn't.").arg(formatType(m_namePool, BuiltinTypes::xsDecimal),
+ formatData(attribute)),
+ ReportContext::XTSE0110);
+ }
+ else
+ {
+
+ if(generateCode)
+ {
+ queueToken(Token(XSLT_VERSION, attribute), to);
+ queueToken(CURLY_LBRACE, to);
+ }
+
+ const xsDecimal version = number->as<Numeric>()->toDecimal();
+ if(version == 2.0)
+ m_processingMode.push(NormalProcessing);
+ else if(version == 1.0)
+ {
+ /* See section 3.6 Stylesheet Element discussing this. */
+ warning(QtXmlPatterns::tr("Running an XSL-T 1.0 stylesheet with a 2.0 processor."));
+ m_processingMode.push(BackwardsCompatible);
+
+ if(setGlobalVersion)
+ {
+ m_parseInfo->staticContext->setCompatModeEnabled(true);
+ m_parseInfo->isBackwardsCompat.push(true);
+ }
+ }
+ else if(version > 2.0)
+ m_processingMode.push(ForwardCompatible);
+ else if(version < 2.0)
+ m_processingMode.push(BackwardsCompatible);
+ }
+
+ if(generateCode)
+ queueOnExit->push(CURLY_RBRACE);
+}
+
+void XSLTTokenizer::handleXMLBase(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isInstruction,
+ const QXmlStreamAttributes *atts)
+{
+ const QXmlStreamAttributes effectiveAtts(atts ? *atts : m_currentAttributes);
+
+ if(effectiveAtts.hasAttribute(QLatin1String("xml:base")))
+ {
+ const QStringRef val(effectiveAtts.value(QLatin1String("xml:base")));
+
+ if(!val.isEmpty())
+ {
+ if(isInstruction)
+ {
+ queueToken(BASEURI, to);
+ queueToken(Token(STRING_LITERAL, val.toString()), to);
+ queueToken(CURLY_LBRACE, to);
+ queueOnExit->push(CURLY_RBRACE);
+ }
+ else
+ {
+ queueToken(DECLARE, to);
+ queueToken(BASEURI, to);
+ queueToken(INTERNAL, to);
+ queueToken(Token(STRING_LITERAL, val.toString()), to);
+ queueToken(SEMI_COLON, to);
+ }
+ }
+ }
+}
+
+void XSLTTokenizer::handleStandardAttributes(const bool isXSLTElement)
+{
+ /* We're not necessarily StartElement, that's why we have atts passed in. */
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ if(m_hasHandledStandardAttributes)
+ return;
+
+ m_hasHandledStandardAttributes = true;
+
+ const QString ns(isXSLTElement ? QString() : CommonNamespaces::XSLT);
+ const int len = m_currentAttributes.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamAttribute &att = m_currentAttributes.at(i);
+
+ if(att.qualifiedName() == QLatin1String("xml:space"))
+ {
+ const QStringRef val(m_currentAttributes.value(CommonNamespaces::XML, QLatin1String("space")));
+
+ /* We raise an error if the value is not recognized.
+ *
+ * Extensible Markup Language (XML) 1.0 (Fourth Edition), 2.10
+ * White Space Handling:
+ *
+ * 'This specification does not give meaning to any value of
+ * xml:space other than "default" and "preserve". It is an error
+ * for other values to be specified; the XML processor may report
+ * the error or may recover by ignoring the attribute specification
+ * or by reporting the (erroneous) value to the application.' */
+ m_stripWhitespace.push(readToggleAttribute(QLatin1String("xml:space"),
+ QLatin1String("default"),
+ QLatin1String("preserve"),
+ &m_currentAttributes));
+ }
+
+ if(att.namespaceUri() != ns)
+ continue;
+
+ switch(toToken(att.name()))
+ {
+ case Type:
+ /* Fallthrough. */
+ case Validation:
+ /* Fallthrough. */
+ case UseAttributeSets:
+ /* Fallthrough. */
+ case Version:
+ /* These are handled by other function such as
+ * handleValidationAttributes() and handleXSLTVersion(). */
+ continue;
+ default:
+ {
+ if(!isXSLTElement) /* validateElement() will take care of it, and we
+ * don't want to flag non-standard XSL-T attributes. */
+ {
+ error(QtXmlPatterns::tr("Unknown XSL-T attribute %1.")
+ .arg(formatKeyword(att.name())),
+ ReportContext::XTSE0805);
+ }
+ }
+ }
+ }
+}
+
+void XSLTTokenizer::handleValidationAttributes(const bool isLRE) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ const QString ns(isLRE ? QString() : CommonNamespaces::XSLT);
+
+ const bool hasValidation = hasAttribute(ns, QLatin1String("validation"));
+ const bool hasType = hasAttribute(ns, QLatin1String("type"));
+
+ if(!hasType && !hasValidation)
+ return;
+
+ if(hasType && hasValidation)
+ {
+ error(QtXmlPatterns::tr("Attribute %1 and %2 are mutually exclusive.")
+ .arg(formatKeyword(QLatin1String("validation")),
+ formatKeyword(QLatin1String("type"))),
+ ReportContext::XTSE1505);
+ }
+
+ /* QXmlStreamReader surely doesn't make this easy. */
+ QXmlStreamAttribute validationAttribute;
+ int len = m_currentAttributes.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamAttribute &at = m_currentAttributes.at(i);
+ if(at.name() == QLatin1String("validation") && at.namespaceUri() == ns)
+ validationAttribute = at;
+ }
+
+ Q_ASSERT_X(!validationAttribute.name().isNull(), Q_FUNC_INFO,
+ "We should always find the attribute.");
+
+ /* We don't care about the return value, we just want to check it's a valid
+ * one. */
+ readAlternativeAttribute(m_validationAlternatives,
+ validationAttribute);
+}
+
+Tokenizer::Token XSLTTokenizer::nextToken(YYLTYPE *const sourceLocator)
+{
+ Q_UNUSED(sourceLocator);
+
+ if(m_tokenSource.isEmpty())
+ {
+ switch(m_state.top())
+ {
+ case OutsideDocumentElement:
+ outsideDocumentElement();
+ break;
+ case InsideStylesheetModule:
+ insideStylesheetModule();
+ break;
+ case InsideSequenceConstructor:
+ insideSequenceConstructor(&m_tokenSource);
+ break;
+ }
+
+ if(m_tokenSource.isEmpty())
+ {
+ *sourceLocator = currentSourceLocator();
+ return Token(END_OF_FILE);
+ }
+ else
+ return m_tokenSource.head()->nextToken(sourceLocator);
+ }
+ else
+ {
+ do
+ {
+ const Token candidate(m_tokenSource.head()->nextToken(sourceLocator));
+ if(candidate.type == END_OF_FILE)
+ m_tokenSource.dequeue();
+ else
+ return candidate;
+ }
+ while(!m_tokenSource.isEmpty());
+
+ /* Now we will resume parsing inside the regular XSL-T(XML) file. */
+ return nextToken(sourceLocator);
+ }
+}
+
+bool XSLTTokenizer::isElement(const XSLTTokenLookup::NodeName &name) const
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement ||
+ tokenType() == QXmlStreamReader::EndElement);
+
+ return currentElementName() == name;
+}
+
+inline bool XSLTTokenizer::isXSLT() const
+{
+ Q_ASSERT_X(tokenType() == QXmlStreamReader::StartElement ||
+ tokenType() == QXmlStreamReader::EndElement,
+ Q_FUNC_INFO, "The current token state must be StartElement or EndElement.");
+ /* Possible optimization: let MaintainingReader set an m_isXSLT which we
+ * read. */
+ return namespaceUri() == CommonNamespaces::XSLT;
+}
+
+void XSLTTokenizer::queueOnExit(QStack<Token> &source,
+ TokenSource::Queue *const destination)
+{
+ while(!source.isEmpty())
+ queueToken(source.pop(), destination);
+}
+
+void XSLTTokenizer::outsideDocumentElement()
+{
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ /* First, we synthesize one of the built-in templates,
+ * see section 6.6 Built-in Template Rules.
+ *
+ * Note that insideStylesheetModule() can be called multiple
+ * times so we can't do it there. */
+ {
+ /* Start with the one for text nodes and attributes.
+ * declare template matches (text() | @*) mode #all
+ * {
+ * text{.}
+ * };
+ */
+
+ /* declare template matches (text() | @*) */
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(TEMPLATE, &m_tokenSource);
+ queueToken(MATCHES, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(TEXT, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+ queueToken(BAR, &m_tokenSource);
+ queueToken(AT_SIGN, &m_tokenSource);
+ queueToken(STAR, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+
+ /* mode #all */
+ queueToken(MODE, &m_tokenSource);
+ queueToken(Token(NCNAME, QLatin1String("#all")), &m_tokenSource);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+
+ /* text{.} { */
+ queueToken(TEXT, &m_tokenSource);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+ queueToken(DOT, &m_tokenSource);
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+
+ /* }; */
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+ queueToken(SEMI_COLON, &m_tokenSource);
+ }
+
+ if(isXSLT() && isStylesheetElement())
+ {
+ handleStandardAttributes(true);
+ QStack<Token> onExitTokens;
+ handleXMLBase(&m_tokenSource, &onExitTokens, false);
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true, 0, false, true);
+ validateElement();
+ queueNamespaceDeclarations(&m_tokenSource, 0, true);
+
+ /* We're a regular stylesheet. */
+
+ pushState(InsideStylesheetModule);
+ insideStylesheetModule();
+ }
+ else
+ {
+ /* We're a simplified stylesheet. */
+
+ if(!hasAttribute(CommonNamespaces::XSLT, QLatin1String("version")))
+ {
+ error(QtXmlPatterns::tr("In a simplified stylesheet module, attribute %1 must be present.")
+ .arg(formatKeyword(QLatin1String("version"))),
+ ReportContext::XTSE0010);
+ }
+
+ QStack<Token> onExitTokens;
+
+ /* We synthesize this as exemplified in
+ * 3.7 Simplified Stylesheet Modules. */
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(TEMPLATE, &m_tokenSource);
+ queueToken(MATCHES, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(SLASH, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+ pushState(InsideSequenceConstructor);
+
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, false, 0, true);
+ handleStandardAttributes(false);
+
+ insideSequenceConstructor(&m_tokenSource, false);
+
+ queueOnExit(onExitTokens, &m_tokenSource);
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+ queueToken(SEMI_COLON, &m_tokenSource);
+ }
+
+ queueToken(APPLY_TEMPLATE, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+
+ break;
+ }
+ default:
+ /* Do nothing. */;
+ }
+ }
+ checkForParseError();
+}
+
+void XSLTTokenizer::queueToken(const Token &token,
+ TokenSource::Queue *const to)
+{
+ TokenSource::Queue *const effective = to ? to : &m_tokenSource;
+
+ effective->enqueue(TokenSource::Ptr(new SingleTokenContainer(token, currentSourceLocator())));
+}
+
+void XSLTTokenizer::pushState(const State nextState)
+{
+ m_state.push(nextState);
+}
+
+void XSLTTokenizer::leaveState()
+{
+ m_state.pop();
+}
+
+void XSLTTokenizer::insideTemplate()
+{
+ const bool hasPriority = hasAttribute(QLatin1String("priority"));
+ const bool hasMatch = hasAttribute(QLatin1String("match"));
+ const bool hasName = hasAttribute(QLatin1String("name"));
+ const bool hasMode = hasAttribute(QLatin1String("mode"));
+ const bool hasAs = hasAttribute(QLatin1String("as"));
+
+ if(!hasMatch &&
+ (hasMode ||
+ hasPriority))
+ {
+ error(QtXmlPatterns::tr("If element %1 has no attribute %2, it cannot have attribute %3 or %4.")
+ .arg(formatKeyword(QLatin1String("template")),
+ formatKeyword(QLatin1String("match")),
+ formatKeyword(QLatin1String("mode")),
+ formatKeyword(QLatin1String("priority"))),
+ ReportContext::XTSE0500);
+ }
+ else if(!hasMatch && !hasName)
+ {
+ error(QtXmlPatterns::tr("Element %1 must have at least one of the attributes %2 or %3.")
+ .arg(formatKeyword(QLatin1String("template")),
+ formatKeyword(QLatin1String("name")),
+ formatKeyword(QLatin1String("match"))),
+ ReportContext::XTSE0500);
+ }
+
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(TEMPLATE, &m_tokenSource);
+
+ if(hasName)
+ {
+ queueToken(NAME, &m_tokenSource);
+ queueToken(Token(QNAME, readAttribute(QLatin1String("name"))), &m_tokenSource);
+ }
+
+ if(hasMatch)
+ {
+ queueToken(MATCHES, &m_tokenSource);
+ queueExpression(readAttribute(QLatin1String("match")), &m_tokenSource);
+ }
+
+ if(hasMode)
+ {
+ const QString modeString(readAttribute(QLatin1String("mode")).simplified());
+
+ if(modeString.isEmpty())
+ {
+ error(QtXmlPatterns::tr("At least one mode must be specified in the %1-attribute on element %2.")
+ .arg(formatKeyword(QLatin1String("mode")),
+ formatKeyword(QLatin1String("template"))),
+ ReportContext::XTSE0500);
+ }
+
+ queueToken(MODE, &m_tokenSource);
+
+ const QStringList modeList(modeString.split(QLatin1Char(' ')));
+
+ for(int i = 0; i < modeList.count(); ++i)
+ {
+ const QString &mode = modeList.at(i);
+
+ queueToken(Token(mode.contains(QLatin1Char(':')) ? QNAME : NCNAME, mode), &m_tokenSource);
+
+ if(i < modeList.count() - 1)
+ queueToken(COMMA, &m_tokenSource);
+ }
+ }
+
+ if(hasPriority)
+ {
+ queueToken(PRIORITY, &m_tokenSource);
+ queueToken(Token(STRING_LITERAL, readAttribute(QLatin1String("priority"))), &m_tokenSource);
+ }
+
+ QStack<Token> onExitTokens;
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ /* queueParams moves the reader so we need to freeze the attributes. */
+ const QXmlStreamAttributes atts(m_currentAttributes);
+ handleStandardAttributes(true);
+ queueToken(LPAREN, &m_tokenSource);
+ queueParams(Template, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+
+ if(hasAs)
+ {
+ queueToken(AS, &m_tokenSource);
+ queueSequenceType(atts.value(QLatin1String("as")).toString());
+ }
+
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+
+ handleXMLBase(&m_tokenSource, &onExitTokens, true, &atts);
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true, &atts);
+ pushState(InsideSequenceConstructor);
+ startStorageOfCurrent(&m_tokenSource);
+ insideSequenceConstructor(&m_tokenSource, onExitTokens, false);
+ queueOnExit(onExitTokens, &m_tokenSource);
+}
+
+void XSLTTokenizer::queueExpression(const QString &expr,
+ TokenSource::Queue *const to,
+ const bool wrapWithParantheses)
+{
+ TokenSource::Queue *const effectiveTo = to ? to : &m_tokenSource;
+
+ if(wrapWithParantheses)
+ queueToken(LPAREN, effectiveTo);
+
+ effectiveTo->enqueue(TokenSource::Ptr(new XQueryTokenizer(expr, queryURI())));
+
+ if(wrapWithParantheses)
+ queueToken(RPAREN, effectiveTo);
+}
+
+void XSLTTokenizer::queueAVT(const QString &expr,
+ TokenSource::Queue *const to)
+{
+ queueToken(AVT, to);
+ queueToken(LPAREN, to);
+ to->enqueue(TokenSource::Ptr(new XQueryTokenizer(expr, queryURI(),
+ XQueryTokenizer::QuotAttributeContent)));
+ queueToken(RPAREN, to);
+}
+
+void XSLTTokenizer::queueSequenceType(const QString &expr)
+{
+ m_tokenSource.enqueue(TokenSource::Ptr(new XQueryTokenizer(expr, queryURI(),
+ XQueryTokenizer::ItemType)));
+}
+
+void XSLTTokenizer::commencingExpression(bool &hasWrittenExpression,
+ TokenSource::Queue *const to)
+{
+ if(hasWrittenExpression)
+ queueToken(COMMA, to);
+ else
+ hasWrittenExpression = true;
+}
+
+void XSLTTokenizer::queueEmptySequence(TokenSource::Queue *const to)
+{
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+}
+
+void XSLTTokenizer::insideChoose(TokenSource::Queue *const to)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ bool hasHandledOtherwise = false;
+ bool hasEncounteredAtLeastOneWhen = false;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT())
+ {
+ QStack<Token> onExitTokens;
+ handleStandardAttributes(true);
+ validateElement();
+
+ switch(currentElementName())
+ {
+ case When:
+ {
+ if(hasHandledOtherwise)
+ {
+ error(QtXmlPatterns::tr("Element %1 must come last.")
+ .arg(formatKeyword(QLatin1String("otherwise"))),
+ ReportContext::XTSE0010);
+ }
+
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+ queueExpression(readAttribute(QLatin1String("test")), to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+ queueToken(LPAREN, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ queueToken(RPAREN, to);
+ Q_ASSERT(tokenType() == QXmlStreamReader::EndElement);
+ queueToken(ELSE, to);
+ hasEncounteredAtLeastOneWhen = true;
+ queueOnExit(onExitTokens, to);
+ break;
+ }
+ case Otherwise:
+ {
+ if(!hasEncounteredAtLeastOneWhen)
+ {
+ error(QtXmlPatterns::tr("At least one %1-element must occur before %2.")
+ .arg(formatKeyword(QLatin1String("when")),
+ formatKeyword(QLatin1String("otherwise"))),
+ ReportContext::XTSE0010);
+ }
+ else if(hasHandledOtherwise)
+ {
+ error(QtXmlPatterns::tr("Only one %1-element can appear.")
+ .arg(formatKeyword(QLatin1String("otherwise"))),
+ ReportContext::XTSE0010);
+ }
+
+ pushState(InsideSequenceConstructor);
+ queueToken(LPAREN, to);
+ insideSequenceConstructor(to, to);
+ queueToken(RPAREN, to);
+ hasHandledOtherwise = true;
+ queueOnExit(onExitTokens, to);
+ break;
+ }
+ default:
+ unexpectedContent();
+ }
+ }
+ else
+ unexpectedContent();
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ if(isXSLT())
+ {
+ switch(currentElementName())
+ {
+ case Choose:
+ {
+ if(!hasEncounteredAtLeastOneWhen)
+ {
+ error(QtXmlPatterns::tr("At least one %1-element must occur inside %2.")
+ .arg(formatKeyword(QLatin1String("when")),
+ formatKeyword(QLatin1String("choose"))),
+ ReportContext::XTSE0010);
+ }
+
+ if(!hasHandledOtherwise)
+ queueEmptySequence(to);
+ return;
+ }
+ case Otherwise:
+ continue;
+ default:
+ unexpectedContent();
+ }
+ }
+ else
+ unexpectedContent();
+ break;
+ }
+ case QXmlStreamReader::Comment:
+ /* Fallthrough. */
+ case QXmlStreamReader::ProcessingInstruction:
+ continue;
+ case QXmlStreamReader::Characters:
+ {
+ /* We ignore regardless of what xml:space says, see step 4 in
+ * 4.2 Stripping Whitespace from the Stylesheet. */
+ if(isWhitespace())
+ continue;
+ /* Fallthrough. */
+ }
+ default:
+ /* Fallthrough. */
+ unexpectedContent();
+ break;
+ }
+ }
+ checkForParseError();
+}
+
+bool XSLTTokenizer::queueSelectOrSequenceConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const QXmlStreamAttributes *const attsP,
+ const bool queueEmptyOnEmpty)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement || attsP);
+ const NodeName elementName(currentElementName());
+ const QXmlStreamAttributes atts(attsP ? *attsP : m_currentAttributes);
+
+ if(atts.hasAttribute(QLatin1String("select")))
+ {
+ queueExpression(atts.value(QLatin1String("select")).toString(), to);
+
+ /* First, verify that we don't have a body. */
+ if(skipSubTree(true))
+ {
+ error(QtXmlPatterns::tr("When attribute %1 is present on %2, a sequence "
+ "constructor cannot be used.").arg(formatKeyword(QLatin1String("select")),
+ formatKeyword(toString(elementName))),
+ code);
+ }
+
+ return true;
+ }
+ else
+ {
+ pushState(InsideSequenceConstructor);
+ if(!insideSequenceConstructor(to, true, queueEmptyOnEmpty) && !emptynessAllowed)
+ {
+ error(QtXmlPatterns::tr("Element %1 must have either a %2-attribute "
+ "or a sequence constructor.").arg(formatKeyword(toString(elementName)),
+ formatKeyword(QLatin1String("select"))),
+ code);
+
+ }
+
+ return false;
+ }
+}
+
+void XSLTTokenizer::queueSimpleContentConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const bool selectOnlyFirst)
+{
+ queueToken(INTERNAL_NAME, to);
+ queueToken(Token(NCNAME, QLatin1String("generic-string-join")), to);
+ queueToken(LPAREN, to);
+
+ /* We have to read the attribute before calling
+ * queueSelectOrSequenceConstructor(), since it advances the reader. */
+ const bool hasSeparator = m_currentAttributes.hasAttribute(QLatin1String("separator"));
+ const QString separatorAVT(m_currentAttributes.value(QLatin1String("separator")).toString());
+
+ queueToken(LPAREN, to);
+ const bool viaSelectAttribute = queueSelectOrSequenceConstructor(code, emptynessAllowed, to);
+ queueToken(RPAREN, to);
+
+ if(selectOnlyFirst)
+ {
+ queueToken(LBRACKET, to);
+ queueToken(Token(NUMBER, QChar::fromLatin1('1')), to);
+ queueToken(RBRACKET, to);
+ }
+
+ queueToken(COMMA, to);
+
+ if(hasSeparator)
+ queueAVT(separatorAVT, to);
+ else
+ {
+ /* The default value depends on whether the value is from @select, or from
+ * the sequence constructor. */
+ queueToken(Token(STRING_LITERAL, viaSelectAttribute ? QString(QLatin1Char(' '))
+ : QString()),
+ to);
+ }
+
+ queueToken(RPAREN, to);
+}
+
+void XSLTTokenizer::queueTextConstructor(QString &chars,
+ bool &hasWrittenExpression,
+ TokenSource::Queue *const to)
+{
+ if(!chars.isEmpty())
+ {
+ commencingExpression(hasWrittenExpression, to);
+ queueToken(TEXT, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(Token(STRING_LITERAL, chars), to);
+ queueToken(CURLY_RBRACE, to);
+ chars.clear();
+ }
+}
+
+void XSLTTokenizer::queueVariableDeclaration(const VariableType variableType,
+ TokenSource::Queue *const to)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ if(variableType == VariableInstruction)
+ {
+ queueToken(LET, to);
+ queueToken(INTERNAL, to);
+ }
+ else if(variableType == VariableDeclaration || variableType == GlobalParameter)
+ {
+ queueToken(DECLARE, to);
+ queueToken(VARIABLE, to);
+ queueToken(INTERNAL, to);
+ }
+
+ queueToken(DOLLAR, to);
+
+ queueExpression(readAttribute(QLatin1String("name")), to, false);
+
+ const bool hasAs = m_currentAttributes.hasAttribute(QLatin1String("as"));
+ if(hasAs)
+ {
+ queueToken(AS, to);
+ queueSequenceType(m_currentAttributes.value(QLatin1String("as")).toString());
+ }
+
+ if(variableType == FunctionParameter)
+ {
+ skipBodyOfParam(ReportContext::XTSE0760);
+ return;
+ }
+
+ /* We must do this here, because queueSelectOrSequenceConstructor()
+ * advances the reader. */
+ const bool hasSelect = hasAttribute(QLatin1String("select"));
+ const bool isRequired = hasAttribute(QLatin1String("required")) ? attributeYesNo(QLatin1String("required")) : false;
+
+ TokenSource::Queue storage;
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0620, true, &storage, 0, false);
+
+ /* XSL-T has some wicked rules, see
+ * 9.3 Values of Variables and Parameters. */
+
+ const bool hasQueuedContent = !storage.isEmpty();
+
+ /* The syntax for global parameters is:
+ *
+ * declare variable $var external := 'defaultValue';
+ */
+ if(variableType == GlobalParameter)
+ queueToken(EXTERNAL, to);
+
+ if(isRequired)
+ {
+ if(hasQueuedContent)
+ {
+ error(QtXmlPatterns::tr("When a parameter is required, a default value "
+ "cannot be supplied through a %1-attribute or "
+ "a sequence constructor.").arg(formatKeyword(QLatin1String("select"))),
+ ReportContext::XTSE0010);
+ }
+ }
+ else
+ {
+ if(hasQueuedContent)
+ {
+ queueToken(ASSIGN, to);
+
+ if(!hasSelect && !hasAs && !hasQueuedContent)
+ queueToken(Token(STRING_LITERAL, QString()), to);
+ else if(hasAs || hasSelect)
+ queueToken(LPAREN, to);
+ else
+ {
+ queueToken(DOCUMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ }
+ }
+ else
+ {
+ if(!hasAs)
+ {
+ queueToken(ASSIGN, to);
+ queueToken(Token(STRING_LITERAL, QString()), to);
+ }
+ else if(variableType == VariableDeclaration || variableType == VariableInstruction)
+ {
+ queueToken(ASSIGN, to);
+ queueEmptySequence(to);
+ }
+ }
+
+ /* storage has tokens if hasSelect or hasQueuedContent is true. */
+ if(hasSelect | hasQueuedContent)
+ *to += storage;
+
+ if(hasQueuedContent)
+ {
+ if(!hasSelect && !hasAs && !hasQueuedContent)
+ queueToken(Token(STRING_LITERAL, QString()), to);
+ else if(hasAs || hasSelect)
+ queueToken(RPAREN, to);
+ else
+ queueToken(CURLY_RBRACE, to);
+ }
+ }
+
+ if(variableType == VariableInstruction)
+ queueToken(RETURN, to);
+ else if(variableType == VariableDeclaration || variableType == GlobalParameter)
+ queueToken(SEMI_COLON, to);
+}
+
+void XSLTTokenizer::startStorageOfCurrent(TokenSource::Queue *const to)
+{
+ queueToken(CURRENT, to);
+ queueToken(CURLY_LBRACE, to);
+}
+
+void XSLTTokenizer::endStorageOfCurrent(TokenSource::Queue *const to)
+{
+ queueToken(CURLY_RBRACE, to);
+}
+
+void XSLTTokenizer::queueNamespaceDeclarations(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isDeclaration)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ Q_ASSERT_X(isDeclaration || queueOnExit,
+ Q_FUNC_INFO,
+ "If isDeclaration is false, queueOnExit must be passed.");
+
+ const QXmlStreamNamespaceDeclarations nss(namespaceDeclarations());
+
+ for(int i = 0; i < nss.count(); ++i)
+ {
+ const QXmlStreamNamespaceDeclaration &at = nss.at(i);
+ queueToken(DECLARE, to);
+ queueToken(NAMESPACE, to);
+ queueToken(Token(NCNAME, at.prefix().toString()), to);
+ queueToken(G_EQ, to);
+ queueToken(Token(STRING_LITERAL, at.namespaceUri().toString()), to);
+
+ if(isDeclaration)
+ {
+ queueToken(INTERNAL, to);
+ queueToken(SEMI_COLON, to);
+ }
+ else
+ {
+ queueToken(CURLY_LBRACE, to);
+ queueOnExit->push(CURLY_RBRACE);
+ }
+ }
+}
+
+bool XSLTTokenizer::insideSequenceConstructor(TokenSource::Queue *const to,
+ const bool initialAdvance,
+ const bool queueEmptyOnEmpty)
+{
+ QStack<Token> onExitTokens;
+ return insideSequenceConstructor(to, onExitTokens, initialAdvance, queueEmptyOnEmpty);
+}
+
+bool XSLTTokenizer::insideSequenceConstructor(TokenSource::Queue *const to,
+ QStack<Token> &onExitTokens,
+ const bool initialAdvance,
+ const bool queueEmptyOnEmpty)
+{
+ bool effectiveInitialAdvance = initialAdvance;
+ bool hasWrittenExpression = false;
+
+ /* Buffer which all text nodes, that might be split up by comments,
+ * processing instructions and CDATA sections, are appended to. */
+ QString characters;
+
+ while(!atEnd())
+ {
+ if(effectiveInitialAdvance)
+ readNext();
+ else
+ effectiveInitialAdvance = true;
+
+ switch(tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ queueTextConstructor(characters, hasWrittenExpression, to);
+ handleXMLBase(to, &onExitTokens);
+
+ pushState(InsideSequenceConstructor);
+
+ commencingExpression(hasWrittenExpression, to);
+
+ if(isXSLT())
+ {
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true);
+ handleStandardAttributes(true);
+ validateElement();
+
+ queueNamespaceDeclarations(to, &onExitTokens);
+
+ switch(currentElementName())
+ {
+ case If:
+ {
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+
+ queueExpression(readAttribute(QLatin1String("test")), to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+
+ queueToken(LPAREN, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+
+ break;
+ }
+ case Choose:
+ {
+ insideChoose(to);
+ break;
+ }
+ case ValueOf:
+ {
+ /* We generate a computed text node constructor. */
+ queueToken(TEXT, to);
+ queueToken(CURLY_LBRACE, to);
+
+ queueSimpleContentConstructor(ReportContext::XTSE0870, true, to,
+ !hasAttribute(QLatin1String("separator")) && m_processingMode.top() == BackwardsCompatible);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Sequence:
+ {
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ parseFallbacksOnly();
+ break;
+ }
+ case Text:
+ {
+ queueToken(TEXT, to);
+ queueToken(CURLY_LBRACE, to);
+
+ queueToken(Token(STRING_LITERAL, readElementText()), to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Variable:
+ {
+ queueVariableDeclaration(VariableInstruction, to);
+
+ /* We wrap the children in parantheses since we may
+ * queue several expressions using the comma operator,
+ * and in that case the let-binding is only in-scope
+ * for the first expression. */
+ queueToken(LPAREN, to);
+
+ /* We don't want a comma outputted, we're expecting an
+ * expression now. */
+ hasWrittenExpression = false;
+
+ onExitTokens.push(RPAREN);
+
+ break;
+ }
+ case CallTemplate:
+ {
+ queueToken(CALL_TEMPLATE, to);
+ queueToken(Token(QNAME, readAttribute(QLatin1String("name"))), to);
+ queueToken(LPAREN, to);
+ queueWithParams(CallTemplate, to);
+ queueToken(RPAREN, to);
+ break;
+ }
+ case ForEach:
+ {
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ queueToken(MAP, to);
+ pushState(InsideSequenceConstructor);
+
+ TokenSource::Queue sorts;
+ queueSorting(false, &sorts);
+
+
+ if(sorts.isEmpty())
+ {
+ startStorageOfCurrent(to);
+ insideSequenceConstructor(to, false);
+ endStorageOfCurrent(to);
+ }
+ else
+ {
+ queueToken(SORT, to);
+ *to += sorts;
+ queueToken(RETURN, to);
+ startStorageOfCurrent(to);
+ insideSequenceConstructor(to, false);
+ endStorageOfCurrent(to);
+ queueToken(END_SORT, to);
+ }
+
+ break;
+ }
+ case XSLTTokenLookup::Comment:
+ {
+ queueToken(COMMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0940, true, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case CopyOf:
+ {
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ // TODO
+
+ if(readNext() == QXmlStreamReader::EndElement)
+ break;
+ else
+ {
+ error(QtXmlPatterns::tr("Element %1 cannot have children.").arg(formatKeyword(QLatin1String("copy-of"))),
+ ReportContext::XTSE0010);
+ }
+ break;
+ }
+ case AnalyzeString:
+ {
+ // TODO
+ skipSubTree();
+ break;
+ }
+ case ResultDocument:
+ {
+ // TODO
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ break;
+ }
+ case Copy:
+ {
+ /* We translate:
+ * <xsl:copy>expr</xsl:copy>
+ * into:
+ *
+ * let $body := expr
+ * return
+ * if(self::element()) then
+ * element internal {node-name()} {$body}
+ * else if(self::document-node()) then
+ * document internal {$body}
+ * else (: This includes comments, processing-instructions,
+ * attributes, and comments. :)
+ * .
+ *
+ * TODO node identity is the same as the old node.
+ * TODO namespace bindings are lost when elements are constructed
+ */
+
+ /* let $body := expr */
+ queueToken(LET, to);
+ queueToken(INTERNAL, to);
+ queueToken(DOLLAR, to);
+ queueToken(Token(NCNAME, QString(QLatin1Char('b'))), to); // TODO we need an internal name
+ queueToken(ASSIGN, to);
+ queueToken(LPAREN, to);
+ pushState(InsideSequenceConstructor);
+ /* Don't queue an empty sequence, we want the dot. */
+ insideSequenceConstructor(to);
+ queueToken(RPAREN, to);
+ queueToken(RETURN, to);
+
+ /* if(self::element()) then */
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+ queueToken(SELF, to);
+ queueToken(COLONCOLON, to);
+ queueToken(ELEMENT, to);
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+
+ /* element internal {node-name()} {$body} */
+ queueToken(ELEMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(Token(NCNAME, QLatin1String("node-name")), to); // TODO what if the default ns changes?
+ queueToken(LPAREN, to);
+ queueToken(DOT, to);
+ queueToken(RPAREN, to);
+ queueToken(CURLY_RBRACE, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(DOLLAR, to);
+ queueToken(Token(NCNAME, QString(QLatin1Char('b'))), to); // TODO we need an internal name
+ queueToken(CURLY_RBRACE, to);
+
+ /* else if(self::document-node()) then */
+ queueToken(ELSE, to);
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+ queueToken(SELF, to);
+ queueToken(COLONCOLON, to);
+ queueToken(DOCUMENT_NODE, to);
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+
+ /* document internal {$body} */
+ queueToken(DOCUMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(DOLLAR, to);
+ queueToken(Token(NCNAME, QString(QLatin1Char('b'))), to); // TODO we need an internal name
+ queueToken(CURLY_RBRACE, to);
+
+ /* else . */
+ queueToken(ELSE, to);
+ queueToken(DOT, to);
+
+ break;
+ }
+ case XSLTTokenLookup::ProcessingInstruction:
+ {
+ queueToken(PROCESSING_INSTRUCTION, to);
+ queueToken(CURLY_LBRACE, to);
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+ queueToken(CURLY_LBRACE, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0880, true, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Document:
+ {
+ handleValidationAttributes(false);
+
+ // TODO base-URI
+ queueToken(DOCUMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Element:
+ {
+ handleValidationAttributes(false);
+
+ // TODO base-URI
+ queueToken(ELEMENT, to);
+ queueToken(INTERNAL, to);
+
+ /* The name. */
+ queueToken(CURLY_LBRACE, to);
+ // TODO only strings allowed, not qname values.
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+
+ /* The sequence constructor. */
+ queueToken(CURLY_LBRACE, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Attribute:
+ {
+ handleValidationAttributes(false);
+
+ // TODO base-URI
+ queueToken(ATTRIBUTE, to);
+ queueToken(INTERNAL, to);
+
+ /* The name. */
+ queueToken(CURLY_LBRACE, to);
+ // TODO only strings allowed, not qname values.
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+
+ /* The sequence constructor. */
+ queueToken(CURLY_LBRACE, to);
+ queueSimpleContentConstructor(ReportContext::XTSE0840,
+ true, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Namespace:
+ {
+ queueToken(NAMESPACE, to);
+
+ /* The name. */
+ queueToken(CURLY_LBRACE, to);
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+
+ /* The sequence constructor. */
+ queueToken(CURLY_LBRACE, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0910,
+ false, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case PerformSort:
+ {
+ /* For:
+ * <xsl:perform-sort select="$in">
+ * <xsl:sort select="@key"/>
+ * </xsl:perform-sort>
+ *
+ * we generate:
+ *
+ * $in map sort order by @key
+ * return .
+ * end_sort
+ */
+
+ /* In XQuery, the sort keys appear after the expression
+ * supplying the initial sequence, while in
+ * xsl:perform-sort, if a sequence constructor is used,
+ * they appear in the opposite order. Hence, we need to
+ * reorder it. */
+
+ /* We store the attributes of xsl:perform-sort, before
+ * queueSorting() advances the reader. */
+ const QXmlStreamAttributes atts(m_currentAttributes);
+
+ TokenSource::Queue sorts;
+ queueSorting(true, &sorts);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE1040,
+ true,
+ to,
+ &atts);
+ /* queueSelectOrSequenceConstructor() positions us on EndElement. */
+ effectiveInitialAdvance = false;
+ queueToken(MAP, to);
+ queueToken(SORT, to);
+ *to += sorts;
+ queueToken(RETURN, to);
+ queueToken(DOT, to);
+ queueToken(END_SORT, to);
+
+ break;
+ }
+ case Message:
+ {
+ // TODO
+ queueEmptySequence(to);
+ skipSubTree();
+ break;
+ }
+ case ApplyTemplates:
+ {
+ if(hasAttribute(QLatin1String("select")))
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ else
+ {
+ queueToken(CHILD, to);
+ queueToken(COLONCOLON, to);
+ queueToken(NODE, to);
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+ }
+
+ bool hasMode = hasAttribute(QLatin1String("mode"));
+ QString mode;
+
+ if(hasMode)
+ mode = readAttribute(QLatin1String("mode")).trimmed();
+
+ queueToken(FOR_APPLY_TEMPLATE, to);
+
+ TokenSource::Queue sorts;
+ queueSorting(false, &sorts, true);
+
+ if(!sorts.isEmpty())
+ {
+ queueToken(SORT, to);
+ *to += sorts;
+ queueToken(RETURN, to);
+ }
+
+ queueToken(APPLY_TEMPLATE, to);
+
+ if(hasMode)
+ {
+ queueToken(MODE, to);
+ queueToken(Token(mode.startsWith(QLatin1Char('#')) ? NCNAME : QNAME, mode), to);
+ }
+
+ queueToken(LPAREN, to);
+ queueWithParams(ApplyTemplates, to, false);
+ queueToken(RPAREN, to);
+
+ if(!sorts.isEmpty())
+ queueToken(END_SORT, to);
+
+ break;
+ }
+ default:
+ unexpectedContent();
+ }
+ continue;
+ }
+ else
+ {
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true);
+ handleStandardAttributes(false);
+ handleValidationAttributes(false);
+
+ /* We're generating an element constructor. */
+ queueNamespaceDeclarations(to, &onExitTokens); // TODO same in the isXSLT() branch
+ queueToken(ELEMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(Token(QNAME, qualifiedName().toString()), to);
+ queueToken(CURLY_LBRACE, to);
+ const int len = m_currentAttributes.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamAttribute &at = m_currentAttributes.at(i);
+
+ /* We don't want to generate constructors for XSL-T attributes. */
+ if(at.namespaceUri() == CommonNamespaces::XSLT)
+ continue;
+
+ queueToken(ATTRIBUTE, to);
+ queueToken(INTERNAL, to);
+
+ queueToken(Token(at.prefix().isEmpty() ? NCNAME : QNAME, at.qualifiedName().toString()), to);
+ queueToken(CURLY_LBRACE, to);
+ queueAVT(at.value().toString(), to);
+ queueToken(CURLY_RBRACE, to);
+ queueToken(COMMA, to);
+ }
+
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ Q_ASSERT(tokenType() == QXmlStreamReader::EndElement || hasError());
+ continue;
+ }
+
+ unexpectedContent();
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ queueTextConstructor(characters, hasWrittenExpression, to);
+ leaveState();
+
+ if(!hasWrittenExpression && queueEmptyOnEmpty)
+ queueEmptySequence(to);
+
+ queueOnExit(onExitTokens, to);
+
+ if(isXSLT())
+ {
+ Q_ASSERT(!isElement(Sequence));
+
+ switch(currentElementName())
+ {
+ /* Fallthrough all these. */
+ case When:
+ case Choose:
+ case ForEach:
+ case Otherwise:
+ case PerformSort:
+ case Message:
+ case ResultDocument:
+ case Copy:
+ case CallTemplate:
+ case Text:
+ case ValueOf:
+ {
+ hasWrittenExpression = true;
+ break;
+ }
+ case If:
+ {
+ queueToken(RPAREN, to);
+ queueToken(ELSE, to);
+ queueEmptySequence(to);
+ break;
+ }
+ case Function:
+ {
+ queueToken(CURLY_RBRACE, to);
+ queueToken(SEMI_COLON, to);
+ break;
+ }
+ case Template:
+ {
+ endStorageOfCurrent(&m_tokenSource);
+ /* TODO, fallthrough to Function. */
+ queueToken(CURLY_RBRACE, to);
+ queueToken(SEMI_COLON, to);
+ break;
+ }
+ default:
+ ;
+ }
+ }
+ else
+ {
+ /* We're closing a direct element constructor. */
+ hasWrittenExpression = true;
+ queueToken(CURLY_RBRACE, to);
+ }
+
+ return hasWrittenExpression;
+ }
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ /* We do nothing, we just ignore them. */
+ continue;
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ continue;
+ else
+ {
+ characters += text().toString();
+ continue;
+ }
+ }
+ default:
+ ;
+ }
+ }
+
+ leaveState();
+ return hasWrittenExpression;
+}
+
+bool XSLTTokenizer::isStylesheetElement() const
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement ||
+ tokenType() == QXmlStreamReader::EndElement);
+
+ const NodeName name = currentElementName();
+ return name == Stylesheet || name == Transform;
+}
+
+void XSLTTokenizer::skipBodyOfParam(const ReportContext::ErrorCode code)
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ const NodeName name(currentElementName());
+
+ if(skipSubTree())
+ {
+ error(QtXmlPatterns::tr("Element %1 cannot have a sequence constructor.")
+ .arg(formatKeyword(toString(name))),
+ code);
+ }
+}
+
+void XSLTTokenizer::queueWithParams(const XSLTTokenLookup::NodeName parentName,
+ TokenSource::Queue *const to,
+ const bool initialAdvance)
+{
+ Q_ASSERT(parentName == ApplyTemplates || parentName == CallTemplate);
+
+ bool effectiveInitialAdvance = initialAdvance;
+ bool hasQueuedParam = false;
+
+ while(!atEnd())
+ {
+ if(effectiveInitialAdvance)
+ readNext();
+ else
+ effectiveInitialAdvance = true;
+
+ switch(tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(hasQueuedParam)
+ queueToken(COMMA, to);
+
+ if(isXSLT() && isElement(WithParam))
+ {
+ if(hasAttribute(QLatin1String("tunnel")) && attributeYesNo(QLatin1String("tunnel")))
+ queueToken(TUNNEL, to);
+
+ queueVariableDeclaration(WithParamVariable, to);
+ hasQueuedParam = true;
+ continue;
+ }
+ else
+ unexpectedContent();
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ if(isElement(parentName))
+ return;
+ else
+ continue;
+ }
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ continue;
+ case QXmlStreamReader::Characters:
+ if(whitespaceToSkip())
+ continue;
+ else
+ return;
+ default:
+ unexpectedContent();
+ }
+ }
+ unexpectedContent();
+}
+
+void XSLTTokenizer::queueParams(const XSLTTokenLookup::NodeName parentName,
+ TokenSource::Queue *const to)
+{
+ bool hasQueuedParam = false;
+
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT() && isElement(Param))
+ {
+ if(hasQueuedParam)
+ queueToken(COMMA, to);
+
+ validateElement();
+
+ if(parentName == Function && m_currentAttributes.hasAttribute(QLatin1String("select")))
+ {
+ error(QtXmlPatterns::tr("The attribute %1 cannot appear on %2, when it is a child of %3.")
+ .arg(formatKeyword(QLatin1String("select")),
+ formatKeyword(QLatin1String("param")),
+ formatKeyword(QLatin1String("function"))),
+ ReportContext::XTSE0760);
+ }
+
+ if(parentName == Function && m_currentAttributes.hasAttribute(QLatin1String("required")))
+ {
+ error(QtXmlPatterns::tr("The attribute %1 cannot appear on %2, when it is a child of %3.")
+ .arg(formatKeyword(QLatin1String("required")),
+ formatKeyword(QLatin1String("param")),
+ formatKeyword(QLatin1String("function"))),
+ ReportContext::XTSE0010);
+ }
+
+ const bool hasTunnel = m_currentAttributes.hasAttribute(QLatin1String("tunnel"));
+ const bool isTunnel = hasTunnel ? attributeYesNo(QLatin1String("tunnel")) : false;
+
+ if(isTunnel)
+ {
+ if(parentName == Function)
+ {
+ /* See W3C public report 5650: http://www.w3.org/Bugs/Public/show_bug.cgi?id=5650 */
+ error(QtXmlPatterns::tr("A parameter in a function cannot be declared to be a tunnel."),
+ ReportContext::XTSE0010);
+ }
+ else
+ queueToken(TUNNEL, to);
+ }
+
+ hasQueuedParam = true;
+ queueVariableDeclaration(parentName == Function ? FunctionParameter : TemplateParameter, to);
+ continue;
+ }
+ else
+ return;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ continue;
+ /* Fallthrough. */
+ }
+ case QXmlStreamReader::EndElement:
+ return;
+ default:
+ ;
+ }
+ }
+}
+
+bool XSLTTokenizer::skipSubTree(const bool exitOnContent)
+{
+ bool hasContent = false;
+ int depth = 0;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ continue;
+ else
+ {
+ hasContent = true;
+ if(exitOnContent)
+ return true;
+
+ break;
+ }
+ }
+ case QXmlStreamReader::StartElement:
+ {
+ hasContent = true;
+ if(exitOnContent)
+ return true;
+
+ ++depth;
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ --depth;
+ break;
+ }
+ default:
+ continue;
+ }
+
+ if(depth == -1)
+ return hasContent;
+ }
+
+ checkForParseError();
+ return hasContent;
+}
+
+void XSLTTokenizer::parseFallbacksOnly()
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ skipSubTree();
+ Q_ASSERT(tokenType() == QXmlStreamReader::EndElement);
+}
+
+void XSLTTokenizer::insideAttributeSet()
+{
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT() && isElement(AttributeSet))
+ {
+ // TODO
+ skipSubTree();
+ }
+ else
+ unexpectedContent();
+ }
+ case QXmlStreamReader::EndElement:
+ return;
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ continue;
+ case QXmlStreamReader::Characters:
+ if(whitespaceToSkip())
+ continue;
+ /* Fallthrough. */
+ default:
+ unexpectedContent();
+ }
+ }
+ unexpectedContent();
+}
+
+void XSLTTokenizer::insideStylesheetModule()
+{
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT())
+ {
+ handleStandardAttributes(true);
+ handleXSLTVersion(0, 0, true, 0, false);
+ validateElement();
+
+ /* Handle the various declarations. */
+ switch(currentElementName())
+ {
+ case Template:
+ insideTemplate();
+ break;
+ case Function:
+ insideFunction();
+ break;
+ case Variable:
+ queueVariableDeclaration(VariableDeclaration, &m_tokenSource);
+ break;
+ case Param:
+ queueVariableDeclaration(GlobalParameter, &m_tokenSource);
+ break;
+ case ImportSchema:
+ {
+ error(QtXmlPatterns::tr("This processor is not Schema-aware and "
+ "therefore %1 cannot be used.").arg(formatKeyword(toString(ImportSchema))),
+ ReportContext::XTSE1660);
+ break;
+ }
+ case Output:
+ {
+ // TODO
+ skipSubTree();
+ break;
+ }
+ case StripSpace:
+ /* Fallthrough. */
+ case PreserveSpace:
+ {
+ // TODO @elements
+ skipSubTree(true);
+ readNext();
+
+ if(!isEndElement())
+ unexpectedContent();
+ break;
+ }
+ case Include:
+ {
+ // TODO
+ if(skipSubTree(true))
+ unexpectedContent();
+ break;
+ }
+ case Import:
+ {
+ // TODO
+ if(skipSubTree(true))
+ unexpectedContent();
+ break;
+ }
+ case Key:
+ {
+ // TODO
+ skipSubTree();
+ break;
+ }
+ case AttributeSet:
+ insideAttributeSet();
+ break;
+ default:
+ if(m_processingMode.top() != ForwardCompatible)
+ unexpectedContent();
+ }
+ }
+ else
+ {
+ /* We have a user-defined data element. See section 3.6.2. */
+
+ if(namespaceUri().isEmpty())
+ {
+ error(QtXmlPatterns::tr("Top level stylesheet elements must be "
+ "in a non-null namespace, which %1 isn't.").arg(formatKeyword(name())),
+ ReportContext::XTSE0130);
+ }
+ else
+ skipSubTree();
+ }
+ break;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ /* Regardless of xml:space, we skip whitespace, see step 4 in
+ * 4.2 Stripping Whitespace from the Stylesheet. */
+ if(isWhitespace())
+ continue;
+
+ unexpectedContent(ReportContext::XTSE0120);
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ if(isXSLT())
+ leaveState();
+
+ break;
+ }
+ default:
+ ;
+ }
+ }
+ checkForParseError();
+}
+
+bool XSLTTokenizer::readToggleAttribute(const QString &localName,
+ const QString &isTrue,
+ const QString &isFalse,
+ const QXmlStreamAttributes *const attsP) const
+{
+ const QXmlStreamAttributes atts(attsP ? *attsP : m_currentAttributes);
+ Q_ASSERT(atts.hasAttribute(localName));
+ const QString value(atts.value(localName).toString());
+
+ if(value == isTrue)
+ return true;
+ else if(value == isFalse)
+ return false;
+ else
+ {
+ error(QtXmlPatterns::tr("The value for attribute %1 on element %2 must either "
+ "be %3 or %4, not %5.").arg(formatKeyword(localName),
+ formatKeyword(name()),
+ formatData(isTrue),
+ formatData(isFalse),
+ formatData(value)),
+ ReportContext::XTSE0020);
+ /* Silences a compiler warning. */
+ return false;
+ }
+}
+
+int XSLTTokenizer::readAlternativeAttribute(const QHash<QString, int> &alternatives,
+ const QXmlStreamAttribute &attr) const
+{
+ const QString value(attr.value().toString().trimmed());
+
+ if(alternatives.contains(value))
+ return alternatives[value];
+
+ error(QtXmlPatterns::tr("Attribute %1 cannot have the value %2.")
+ .arg(formatKeyword(attr.name().toString()),
+ formatData(attr.value().toString())),
+ ReportContext::XTSE0020);
+ return 0; /* Silence compiler warning. */
+}
+
+bool XSLTTokenizer::attributeYesNo(const QString &localName) const
+{
+ return readToggleAttribute(localName, QLatin1String("yes"), QLatin1String("no"));
+}
+
+void XSLTTokenizer::queueSorting(const bool oneSortRequired,
+ TokenSource::Queue *const to,
+ const bool speciallyTreatWhitespace)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ const NodeName elementName(currentElementName());
+ bool hasQueuedOneSort = false;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::EndElement:
+ {
+ /* Let's say we have no sequence constructor, but only
+ * ignorable space. In that case we will actually loop
+ * infinitely if we don't have this check. */
+ if(isXSLT())
+ {
+ switch(currentElementName())
+ {
+ case PerformSort:
+ /* Fallthrough. */
+ case ForEach:
+ /* Fallthrough. */
+ case ApplyTemplates:
+ return;
+ default:
+ ;
+ }
+ }
+ continue;
+ }
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT() && isElement(Sort))
+ {
+ if(hasQueuedOneSort)
+ queueToken(COMMA, to);
+
+ /* sorts are by default stable. */
+ if(hasAttribute(QLatin1String("stable")))
+ {
+ if(hasQueuedOneSort)
+ {
+ error(QtXmlPatterns::tr("The attribute %1 can only appear on "
+ "the first %2 element.").arg(formatKeyword(QLatin1String("stable")),
+ formatKeyword(QLatin1String("sort"))),
+ ReportContext::XTSE0020);
+ }
+
+ if(attributeYesNo(QLatin1String("stable")))
+ queueToken(STABLE, to);
+ }
+
+ if(!hasQueuedOneSort)
+ {
+ queueToken(ORDER, to);
+ queueToken(BY, to);
+ }
+
+ /* We store a copy such that we can use them after
+ * queueSelectOrSequenceConstructor() advances the reader. */
+ const QXmlStreamAttributes atts(m_currentAttributes);
+
+ const int before = to->count();
+
+ // TODO This doesn't work as is. @data-type can be an AVT.
+ if(atts.hasAttribute(QLatin1String("data-type")))
+ {
+ if(readToggleAttribute(QLatin1String("data-type"),
+ QLatin1String("text"),
+ QLatin1String("number"),
+ &atts))
+ queueToken(Token(NCNAME, QLatin1String("string")), to);
+ else
+ queueToken(Token(NCNAME, QLatin1String("number")), to);
+ }
+ /* We queue these parantheses for the sake of the function
+ * call for attribute data-type. In the case we don't have
+ * such an attribute, the parantheses are just redundant. */
+ queueToken(LPAREN, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE1015,
+ true,
+ to,
+ 0,
+ false);
+ /* If neither a select attribute or a sequence constructor is supplied,
+ * we're supposed to use the context item. */
+ queueToken(RPAREN, to);
+ if(before == to->count())
+ queueToken(DOT, to);
+
+ // TODO case-order
+ // TODO lang
+
+ // TODO This doesn't work as is. @order can be an AVT, and so can case-order and lang.
+ if(atts.hasAttribute(QLatin1String("order")) && readToggleAttribute(QLatin1String("order"),
+ QLatin1String("descending"),
+ QLatin1String("ascending"),
+ &atts))
+ {
+ queueToken(DESCENDING, to);
+ }
+ else
+ {
+ /* This is the default. */
+ queueToken(ASCENDING, to);
+ }
+
+ if(atts.hasAttribute(QLatin1String("collation")))
+ {
+ queueToken(INTERNAL, to);
+ queueToken(COLLATION, to);
+ queueAVT(atts.value(QLatin1String("collation")).toString(), to);
+ }
+
+ hasQueuedOneSort = true;
+ continue;
+ }
+ else
+ break;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ if(speciallyTreatWhitespace && isWhitespace())
+ continue;
+
+ if(QXmlStreamReader::Characters && whitespaceToSkip())
+ continue;
+
+ /* We have an instruction which is a text node, we're done. */
+ break;
+ }
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ continue;
+ default:
+ unexpectedContent();
+
+ };
+ if(oneSortRequired && !hasQueuedOneSort)
+ {
+ error(QtXmlPatterns::tr("At least one %1 element must appear as child of %2.")
+ .arg(formatKeyword(QLatin1String("sort")), formatKeyword(toString(elementName))),
+ ReportContext::XTSE0010);
+ }
+ else
+ return;
+ }
+ checkForParseError();
+}
+
+void XSLTTokenizer::insideFunction()
+{
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(FUNCTION, &m_tokenSource);
+ queueToken(INTERNAL, &m_tokenSource);
+ queueToken(Token(QNAME, readAttribute(QLatin1String("name"))), &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ const QString expectedType(hasAttribute(QLatin1String("as")) ? readAttribute(QLatin1String("as")): QString());
+
+ if(hasAttribute(QLatin1String("override")))
+ {
+ /* We currently have no external functions, so we don't pass it on currently. */
+ attributeYesNo(QLatin1String("override"));
+ }
+
+ queueParams(Function, &m_tokenSource);
+
+ queueToken(RPAREN, &m_tokenSource);
+
+ if(!expectedType.isNull())
+ {
+ queueToken(AS, &m_tokenSource);
+ queueSequenceType(expectedType);
+ }
+
+ QStack<Token> onExitTokens;
+ handleXMLBase(&m_tokenSource, &onExitTokens, true, &m_currentAttributes);
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(&m_tokenSource, onExitTokens, false);
+ /* We don't queue CURLY_RBRACE, because it's done in
+ * insideSequenceConstructor(). */
+}
+
+YYLTYPE XSLTTokenizer::currentSourceLocator() const
+{
+ YYLTYPE retval;
+ retval.first_line = lineNumber();
+ retval.first_column = columnNumber();
+ return retval;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/parser/qxslttokenizer_p.h b/src/xmlpatterns/parser/qxslttokenizer_p.h
new file mode 100644
index 0000000..cb14114
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenizer_p.h
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XSLTTokenizer_H
+#define Patternist_XSLTTokenizer_H
+
+#include <QQueue>
+#include <QStack>
+#include <QUrl>
+
+#include "qmaintainingreader_p.h"
+#include "qreportcontext_p.h"
+#include "qtokenizer_p.h"
+#include "qxslttokenlookup_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A TokenSource which contains one Tokenizer::Token.
+ *
+ * One possible way to optimize this is to let SingleTokenContainer
+ * actually contain a list of tokens, such that XSLTTokenizer::queueToken()
+ * could append to that, instead of instansiating a SingleTokenContainer
+ * all the time.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SingleTokenContainer : public TokenSource
+ {
+ public:
+ inline SingleTokenContainer(const Tokenizer::Token &token,
+ const YYLTYPE &location);
+
+ virtual Tokenizer::Token nextToken(YYLTYPE *const sourceLocator);
+ private:
+ const Tokenizer::Token m_token;
+ const YYLTYPE m_location;
+ bool m_hasDelivered;
+ };
+
+ SingleTokenContainer::SingleTokenContainer(const Tokenizer::Token &token,
+ const YYLTYPE &location) : m_token(token)
+ , m_location(location)
+ , m_hasDelivered(false)
+ {
+ }
+
+ /**
+ * @short Tokenizes XSL-T 2.0 documents.
+ *
+ * XSLTTokenizer takes in its constructor a pointer to a QIODevice which is
+ * supposed to contain an XSL-T document. XSLTTokenizer then rewrites that
+ * document into XQuery tokens delivered via nextToken(), which the regular
+ * XQuery parser then reads. Hence, the XSL-T language is rewritten into
+ * XQuery code, slightly extended to handle the featuress specific to
+ * XSL-T.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class XSLTTokenizer : public Tokenizer
+ , private MaintainingReader<XSLTTokenLookup>
+ {
+ public:
+ /**
+ * XSLTTokenizer do not own @p queryDevice.
+ */
+ XSLTTokenizer(QIODevice *const queryDevice,
+ const QUrl &location,
+ const ReportContext::Ptr &context,
+ const NamePool::Ptr &np);
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator);
+
+ /**
+ * For XSLT we don't need this mechanism, so we do nothing.
+ */
+ virtual int commenceScanOnly();
+
+ /**
+ * For XSLT we don't need this mechanism, so we do nothing.
+ */
+ virtual void resumeTokenizationFrom(const int position);
+
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo);
+
+ virtual QUrl documentURI() const
+ {
+ return queryURI();
+ }
+
+ protected:
+ virtual bool isAnyAttributeAllowed() const;
+
+ private:
+ inline void validateElement() const;
+
+ YYLTYPE currentSourceLocator() const;
+
+ enum State
+ {
+ OutsideDocumentElement,
+ InsideStylesheetModule,
+ InsideSequenceConstructor
+ };
+
+ enum VariableType
+ {
+ FunctionParameter,
+ GlobalParameter,
+ TemplateParameter,
+ VariableDeclaration,
+ VariableInstruction,
+ WithParamVariable
+ };
+
+ void queueNamespaceDeclarations(TokenSource::Queue *const ts,
+ QStack<Token> *const target,
+ const bool isDeclaration = false);
+
+ inline void queueToken(const Token &token,
+ TokenSource::Queue *const ts);
+ void queueEmptySequence(TokenSource::Queue *const to);
+ void queueSequenceType(const QString &expr);
+ /**
+ * If @p emptynessAllowed is @c true, the @c select attribute may
+ * be empty while there also is no sequence constructor.
+ */
+ void queueSimpleContentConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const bool selectOnlyFirst = false);
+ /**
+ * Tokenizes and queues @p expr as if it was an attribute value
+ * template.
+ */
+ void queueAVT(const QString &expr,
+ TokenSource::Queue *const to);
+
+ void hasWrittenExpression(bool &beacon);
+ void commencingExpression(bool &hasWrittenExpression,
+ TokenSource::Queue *const to);
+
+ void outsideDocumentElement();
+ void insideChoose(TokenSource::Queue *const to);
+ void insideFunction();
+
+ bool attributeYesNo(const QString &localName) const;
+
+ /**
+ * Scans/skips @c xsl:fallback elements only. This is the case of the
+ * children of @c xsl:sequence, for instance.
+ */
+ void parseFallbacksOnly();
+
+ /**
+ * Returns true if the current element is either @c stylesheet
+ * or the synonym @c transform.
+ *
+ * This function assumes that m_reader is positioned at an element
+ * and that the namespace is XSL-T.
+ */
+ bool isStylesheetElement() const;
+
+ /**
+ * Returns true if the current element name is @p name.
+ *
+ * It is assumed that the namespace is XSL-T and that the current
+ * state in m_reader is either QXmlStreamReader::StartElement or
+ * QXmlStreamReader::EndElement.
+ */
+ bool isElement(const NodeName &name) const;
+
+ /**
+ * Queues a text constructor for @p chars, if @p chars is
+ * not empty.
+ */
+ void queueTextConstructor(QString &chars,
+ bool &hasWrittenExpression,
+ TokenSource::Queue *const to);
+
+ /**
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#stylesheet-structure">XSL
+ * Transformations (XSLT) Version 2, 3.6 Stylesheet Element</a>
+ */
+ void insideStylesheetModule();
+ void insideTemplate();
+
+ /**
+ * Takes @p expr for an XPath expression, and pushes the necessary
+ * things for having it delivered as a stream of token, appropriate
+ * for Effective Boolean Value parsing.
+ */
+ void queueExpression(const QString &expr,
+ TokenSource::Queue *const to,
+ const bool wrapWithParantheses = true);
+
+ void skipBodyOfParam(const ReportContext::ErrorCode code);
+
+ void queueParams(const NodeName parentName,
+ TokenSource::Queue *const to);
+
+ /**
+ * Used for @c xsl:apply-templates and @c xsl:call-templates.
+ */
+ void queueWithParams(const NodeName parentName,
+ TokenSource::Queue *const to,
+ const bool initialAdvance = true);
+
+ /**
+ * Queues an @c xsl:variable declaration. If @p isInstruction is @c
+ * true, it is assumed to be a an instruction, otherwise a top-level
+ * declaration element.
+ */
+ void queueVariableDeclaration(const VariableType variableType,
+ TokenSource::Queue *const to);
+
+ /**
+ * Skips the current sub-tree.
+ *
+ * If text nodes that aren't strippable whitespace, or elements are
+ * encountered, @c true is returned, otherwise @c false.
+ *
+ * If @p exitOnContent is @c true, this function exits immediately
+ * if content is encountered for which it would return @c false.
+ */
+ bool skipSubTree(const bool exitOnContent = false);
+
+ /**
+ * Queues the necessary tokens for the expression that is either
+ * supplied using a @c select attribute or a sequence constructor,
+ * while doing the necessary error handling for ensuring they are
+ * mutually exclusive.
+ *
+ * It is assumed that the current state of m_reader is
+ * QXmlStreamReader::StartElement, or that the attributes for the
+ * element is supplied through @p atts. This function advances m_reader
+ * up until the corresponding QXmlStreamReader::EndElement.
+ *
+ * If @p emptynessAllowed is @c false, the element must either have a
+ * sequence constructor or a @c select attribute. If @c true, both may
+ * be absent.
+ *
+ * Returns @c true if the queued expression was supplied through the
+ * @c select attribute otherwise @c false.
+ */
+ bool queueSelectOrSequenceConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const QXmlStreamAttributes *const atts = 0,
+ const bool queueEmptyOnEmpty = true);
+
+ /**
+ * If @p initialAdvance is @c true, insideSequenceConstructor() will
+ * advance m_reader, otherwise it won't. Not doing so is useful
+ * when the caller is already inside a sequence constructor.
+ *
+ * Returns @c true if a sequence constructor was found and queued.
+ * Returns @c false if none was found, and the empty sequence was
+ * synthesized.
+ */
+ bool insideSequenceConstructor(TokenSource::Queue *const to,
+ const bool initialAdvance = true,
+ const bool queueEmptyOnEmpty = true);
+
+ bool insideSequenceConstructor(TokenSource::Queue *const to,
+ QStack<Token> &queueOnExit,
+ const bool initialAdvance = true,
+ const bool queueEmptyOnEmpty = true);
+
+ void insideAttributeSet();
+ void pushState(const State nextState);
+ void leaveState();
+
+ /**
+ * @short Handles @c xml:space and standard attributes.
+ *
+ * If @p isXSLTElement is @c true, the current element is an XSL-T
+ * element, as opposed to a Literal Result Element.
+ *
+ * handleStandardAttributes() must be called before validateElement(),
+ * because the former determines the version in use, and
+ * validateElement() depends on that.
+ *
+ * The core of this function can't be run many times because it pushes
+ * whitespace handling onto m_stripWhitespace.
+ * m_hasHandledStandardAttributes protects helping against this.
+ *
+ * @see validateElement()
+ * @see <a href="http://www.w3.org/TR/xslt20/#standard-attributes">XSL
+ * Transformations (XSLT) Version 2.0, 3.5 Standard Attributes</a>
+ */
+ void handleStandardAttributes(const bool isXSLTElement);
+
+ /**
+ * @short Sends the tokens in @p source to @p destination.
+ */
+ inline void queueOnExit(QStack<Token> &source,
+ TokenSource::Queue *const destination);
+
+ /**
+ * Handles the @c type and @c validation attribute on instructions and
+ * literal result elements.
+ *
+ * @p isLRE should be true if the current element is not in the XSL-T
+ * namespace, that is if it's a Literal Result Element.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#validation">XSL
+ * Transformations (XSLT) Version 2.0, 19.2 Validation</a>
+ */
+ void handleValidationAttributes(const bool isLRE) const;
+
+ void unexpectedContent(const ReportContext::ErrorCode code = ReportContext::XTSE0010) const;
+
+ void checkForParseError() const;
+
+ inline void startStorageOfCurrent(TokenSource::Queue *const to);
+ inline void endStorageOfCurrent(TokenSource::Queue *const to);
+
+ /**
+ * Checks that @p attribute has a value in accordance with what
+ * is allowed and supported.
+ */
+ void handleXSLTVersion(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isXSLTElement,
+ const QXmlStreamAttributes *atts = 0,
+ const bool generateCode = true,
+ const bool setGlobalVersion = false);
+
+ /**
+ * @short Generates code for reflecting @c xml:base attributes.
+ */
+ void handleXMLBase(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isInstruction = true,
+ const QXmlStreamAttributes *atts = 0);
+
+ /**
+ * Concatenates text nodes, ignores comments and processing
+ * instructions, and raises errors on everything else.
+ *
+ * Hence, similar to QXmlStreamReader::readElementText(), except
+ * for error handling.
+ */
+ QString readElementText();
+
+ /**
+ * Tokenizes and validate xsl:sort statements, if any, until
+ * other content is encountered. The produced tokens are returned
+ * in a list.
+ *
+ * If @p oneSortRequired, at least one @c sort element must appear,
+ * otherwise an error is raised.
+ *
+ * If @p speciallyTreatWhitespace whitespace will be treated as if it
+ * was one of the elements mentioned in step 4 in section 4.2 Stripping
+ * Whitespace from the Stylesheet.
+ */
+ void queueSorting(const bool oneSortRequired,
+ TokenSource::Queue *const to,
+ const bool speciallyTreatWhitespace = false);
+
+ static ElementDescription<XSLTTokenLookup>::Hash createElementDescriptions();
+ static QHash<QString, int> createValidationAlternatives();
+ static QSet<NodeName> createStandardAttributes();
+
+ /**
+ * Reads the attribute by name @p attributeName, and returns @c true if
+ * its value is @p isTrue, @c false if it is @p isFalse, and raise an
+ * error otherwise.
+ */
+ bool readToggleAttribute(const QString &attributeName,
+ const QString &isTrue,
+ const QString &isFalse,
+ const QXmlStreamAttributes *const atts = 0) const;
+
+ int readAlternativeAttribute(const QHash<QString, int> &alternatives,
+ const QXmlStreamAttribute &attr) const;
+
+ /**
+ * Returns @c true if the current text node can be skipped without
+ * it leading to a validation error, with respect to whitespace.
+ */
+ inline bool whitespaceToSkip() const;
+
+ const QUrl m_location;
+ const NamePool::Ptr m_namePool;
+ QStack<State> m_state;
+ TokenSource::Queue m_tokenSource;
+
+ enum ProcessMode
+ {
+ BackwardsCompatible,
+ ForwardCompatible,
+ NormalProcessing
+ };
+
+ /**
+ * Whether we're processing in Forwards-Compatible or
+ * Backwards-Compatible mode.
+ *
+ * This is set by handleStandardAttributes().
+ *
+ * ParserContext have similar information in
+ * ParserContext::isBackwardsCompat. A big distinction is that both the
+ * tokenizer and the parser buffer tokens and have positions disjoint
+ * to each other. E.g, the state the parser has when reducing into
+ * non-terminals, is different from the tokenizer's.
+ */
+ QStack<ProcessMode> m_processingMode;
+
+ /**
+ * Returns @c true if the current state in m_reader is in the XSLT
+ * namespace. It is assumed that the current state is an element.
+ */
+ inline bool isXSLT() const;
+
+ const QHash<QString, int> m_validationAlternatives;
+
+ ParserContext::Ptr m_parseInfo;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/qxslttokenlookup.cpp b/src/xmlpatterns/parser/qxslttokenlookup.cpp
new file mode 100644
index 0000000..4730427
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup.cpp
@@ -0,0 +1,3006 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* NOTE: This file is AUTO GENERATED by qtokenautomaton2cpp.xsl. */
+
+#include "qxslttokenlookup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XSLTTokenLookup::NodeName XSLTTokenLookup::classifier2(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ if(data[1] == 115)
+
+
+ return As;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+ if (data[1] == 100)
+
+
+ {
+
+
+ return Id;
+
+ }
+
+ else if (data[1] == 102)
+
+
+ {
+
+
+ return If;
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier3(const QChar *data)
+
+ {
+ if (data[0] == 107)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Key;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Use;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier4(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 112, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Copy;
+
+ }
+
+ else if (data[0] == 104)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 101, 102
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Href;
+
+ }
+
+ else if (data[0] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Lang;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Mode;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Name;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Sort;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+ if (data[2] == 115)
+
+
+ {
+
+ if(data[3] == 116)
+
+
+ return Test;
+
+ }
+
+ else if (data[2] == 120)
+
+
+ {
+
+ if(data[3] == 116)
+
+
+ return Text;
+
+ }
+
+
+ }
+
+ else if (data[1] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Type;
+
+ }
+
+
+ }
+
+ else if (data[0] == 119)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 101, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return When;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier5(const QChar *data)
+
+ {
+ if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 97, 103, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Flags;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 99, 104
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Match;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 100, 101, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Order;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 114, 97, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Param;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 103, 101, 120
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Regex;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier6(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 111, 111, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Choose;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 109, 97, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Format;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+ if (data[1] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 111, 114, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Import;
+
+ }
+
+ else if (data[1] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 110, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Indent;
+
+ }
+
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 116, 104, 111, 100
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Method;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 116, 112, 117, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Output;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 99, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Select;
+
+ }
+
+ else if (data[1] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 98, 108, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Stable;
+
+ }
+
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 110, 110, 101, 108
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Tunnel;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier7(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+ if (data[1] == 111)
+
+
+ {
+ if (data[2] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 101, 110, 116
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Comment;
+
+ }
+
+ else if (data[2] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 121, 45, 111, 102
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 4) == 0)
+
+
+ return CopyOf;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Element;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Include;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 115, 97, 103, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Message;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 114, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Version;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier8(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 99, 117, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Document;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+ if (data[1] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 109, 101, 110, 116, 115
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Elements;
+
+ }
+
+ else if (data[1] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 111, 100, 105, 110, 103
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Encoding;
+
+ }
+
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+ if (data[1] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 45, 101, 97, 99, 104
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return ForEach;
+
+ }
+
+ else if (data[1] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 116, 105, 111, 110
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Function;
+
+ }
+
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 118, 101, 114, 114, 105, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Override;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 105, 111, 114, 105, 116, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Priority;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 113, 117, 105, 114, 101, 100
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Required;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 113, 117, 101, 110, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Sequence;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 109, 112, 108, 97, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Template;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101, 45, 119, 104, 101, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return UseWhen;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+ if (data[1] == 97)
+
+
+ {
+ if (data[2] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 101, 45, 111, 102
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return ValueOf;
+
+ }
+
+ else if (data[2] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 97, 98, 108, 101
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Variable;
+
+ }
+
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier9(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 116, 114, 105, 98, 117, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Attribute;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 108, 108, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Collation;
+
+ }
+
+ else if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 97, 45, 116, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return DataType;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Namespace;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 104, 101, 114, 119, 105, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Otherwise;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 112, 97, 114, 97, 116, 111, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Separator;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 109, 105, 110, 97, 116, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Terminate;
+
+ }
+
+ else if (data[1] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 110, 115, 102, 111, 114, 109
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Transform;
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier10(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 115, 101, 45, 111, 114, 100, 101, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return CaseOrder;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 100, 105, 97, 45, 116, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return MediaType;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 116)
+
+
+ {
+ if (data[2] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 100, 97, 108, 111, 110, 101
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Standalone;
+
+ }
+
+ else if (data[2] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 115, 104, 101, 101, 116
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Stylesheet;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108, 105, 100, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return Validation;
+
+ }
+
+ else if (data[0] == 119)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 116, 104, 45, 112, 97, 114, 97, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return WithParam;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier11(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 116, 114, 105, 112, 45, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 11) == 0)
+
+
+ return StripSpace;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier12(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101, 114, 102, 111, 114, 109, 45, 115, 111, 114, 116
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 12) == 0)
+
+
+ return PerformSort;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier13(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return AttributeSet;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108, 108, 45, 116, 101, 109, 112, 108, 97, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return CallTemplate;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 112, 111, 114, 116, 45, 115, 99, 104, 101, 109, 97
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return ImportSchema;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier14(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 97, 108, 121, 122, 101, 45, 115, 116, 114, 105, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return AnalyzeString;
+
+ }
+
+ else if (data[0] == 100)
+
+
+ {
+ if (data[1] == 111)
+
+
+ {
+ if (data[2] == 99)
+
+
+ {
+ if (data[3] == 116)
+
+
+ {
+ if (data[4] == 121)
+
+
+ {
+ if (data[5] == 112)
+
+
+ {
+ if (data[6] == 101)
+
+
+ {
+ if (data[7] == 45)
+
+
+ {
+ if (data[8] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 98, 108, 105, 99
+ };
+ if(memcmp(&data[9], &string, sizeof(QChar) * 5) == 0)
+
+
+ return DoctypePublic;
+
+ }
+
+ else if (data[8] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 121, 115, 116, 101, 109
+ };
+ if(memcmp(&data[9], &string, sizeof(QChar) * 5) == 0)
+
+
+ return DoctypeSystem;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 116, 112, 117, 116, 45, 118, 101, 114, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return OutputVersion;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 101, 115, 101, 114, 118, 101, 45, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return PreserveSpace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier15(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 112, 108, 121, 45, 116, 101, 109, 112, 108, 97, 116, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ApplyTemplates;
+
+ }
+
+ else if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 121, 116, 101, 45, 111, 114, 100, 101, 114, 45, 109, 97, 114, 107
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ByteOrderMark;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 112, 121, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return CopyNamespaces;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 117, 108, 116, 45, 100, 111, 99, 117, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ResultDocument;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 104, 101, 109, 97, 45, 108, 111, 99, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return SchemaLocation;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier17(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 45, 99, 111, 108, 108, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 17) == 0)
+
+
+ return DefaultCollation;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier18(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116, 45, 118, 97, 108, 105, 100, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return DefaultValidation;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 104, 101, 114, 105, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return InheritNamespaces;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return MatchingSubstring;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 109, 97, 108, 105, 122, 97, 116, 105, 111, 110, 45, 102, 111, 114, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return NormalizationForm;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+ if (data[1] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 99, 108, 97, 114, 101, 45, 112, 114, 101, 102, 105, 120, 101, 115
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 16) == 0)
+
+
+ return UndeclarePrefixes;
+
+ }
+
+ else if (data[1] == 115)
+
+
+ {
+ if (data[2] == 101)
+
+
+ {
+ if (data[3] == 45)
+
+
+ {
+ if (data[4] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116, 115
+ };
+ if(memcmp(&data[5], &string, sizeof(QChar) * 13) == 0)
+
+
+ return UseAttributeSets;
+
+ }
+
+ else if (data[4] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 97, 114, 97, 99, 116, 101, 114, 45, 109, 97, 112, 115
+ };
+ if(memcmp(&data[5], &string, sizeof(QChar) * 13) == 0)
+
+
+ return UseCharacterMaps;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier20(const QChar *data)
+
+ {
+ if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 100, 101, 45, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 19) == 0)
+
+
+ return IncludeContentType;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 105, 116, 45, 120, 109, 108, 45, 100, 101, 99, 108, 97, 114, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 19) == 0)
+
+
+ return OmitXmlDeclaration;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier21(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 99, 97, 112, 101, 45, 117, 114, 105, 45, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 21) == 0)
+
+
+ return EscapeUriAttributes;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier22(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 97, 116, 97, 45, 115, 101, 99, 116, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return CdataSectionElements;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 112, 117, 116, 45, 116, 121, 112, 101, 45, 97, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return InputTypeAnnotations;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 110, 45, 109, 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return NonMatchingSubstring;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 111, 99, 101, 115, 115, 105, 110, 103, 45, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return ProcessingInstruction;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier23(const QChar *data)
+
+ {
+ if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 99, 108, 117, 100, 101, 45, 114, 101, 115, 117, 108, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 22) == 0)
+
+
+ return ExcludeResultPrefixes;
+
+ }
+
+ else if (data[0] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 97, 116, 104, 45, 100, 101, 102, 97, 117, 108, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 22) == 0)
+
+
+ return XpathDefaultNamespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier26(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 120, 116, 101, 110, 115, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 26) == 0)
+
+
+ return ExtensionElementPrefixes;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::toToken(const QChar *data, int length)
+ {
+ switch(length)
+ {
+
+ case 2:
+ return classifier2(data);
+
+
+ case 3:
+ return classifier3(data);
+
+
+ case 4:
+ return classifier4(data);
+
+
+ case 5:
+ return classifier5(data);
+
+
+ case 6:
+ return classifier6(data);
+
+
+ case 7:
+ return classifier7(data);
+
+
+ case 8:
+ return classifier8(data);
+
+
+ case 9:
+ return classifier9(data);
+
+
+ case 10:
+ return classifier10(data);
+
+
+ case 11:
+ return classifier11(data);
+
+
+ case 12:
+ return classifier12(data);
+
+
+ case 13:
+ return classifier13(data);
+
+
+ case 14:
+ return classifier14(data);
+
+
+ case 15:
+ return classifier15(data);
+
+
+ case 17:
+ return classifier17(data);
+
+
+ case 18:
+ return classifier18(data);
+
+
+ case 20:
+ return classifier20(data);
+
+
+ case 21:
+ return classifier21(data);
+
+
+ case 22:
+ return classifier22(data);
+
+
+ case 23:
+ return classifier23(data);
+
+
+ case 26:
+ return classifier26(data);
+
+
+ default:
+ return NoKeyword;
+ }
+ }
+
+
+ QString XSLTTokenLookup::toString(NodeName token)
+ {
+ const unsigned short *data = 0;
+ int length = 0;
+
+ switch(token)
+ {
+
+ case AnalyzeString:
+ {
+ static const unsigned short staticallyStoredAnalyzeString[] =
+ {
+ 97, 110, 97, 108, 121, 122, 101, 45, 115, 116, 114, 105, 110, 103, 0
+ };
+ data = staticallyStoredAnalyzeString;
+ length = 14;
+ break;
+ }
+
+ case ApplyTemplates:
+ {
+ static const unsigned short staticallyStoredApplyTemplates[] =
+ {
+ 97, 112, 112, 108, 121, 45, 116, 101, 109, 112, 108, 97, 116, 101, 115, 0
+ };
+ data = staticallyStoredApplyTemplates;
+ length = 15;
+ break;
+ }
+
+ case As:
+ {
+ static const unsigned short staticallyStoredAs[] =
+ {
+ 97, 115, 0
+ };
+ data = staticallyStoredAs;
+ length = 2;
+ break;
+ }
+
+ case Attribute:
+ {
+ static const unsigned short staticallyStoredAttribute[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 0
+ };
+ data = staticallyStoredAttribute;
+ length = 9;
+ break;
+ }
+
+ case AttributeSet:
+ {
+ static const unsigned short staticallyStoredAttributeSet[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116, 0
+ };
+ data = staticallyStoredAttributeSet;
+ length = 13;
+ break;
+ }
+
+ case ByteOrderMark:
+ {
+ static const unsigned short staticallyStoredByteOrderMark[] =
+ {
+ 98, 121, 116, 101, 45, 111, 114, 100, 101, 114, 45, 109, 97, 114, 107, 0
+ };
+ data = staticallyStoredByteOrderMark;
+ length = 15;
+ break;
+ }
+
+ case CallTemplate:
+ {
+ static const unsigned short staticallyStoredCallTemplate[] =
+ {
+ 99, 97, 108, 108, 45, 116, 101, 109, 112, 108, 97, 116, 101, 0
+ };
+ data = staticallyStoredCallTemplate;
+ length = 13;
+ break;
+ }
+
+ case CaseOrder:
+ {
+ static const unsigned short staticallyStoredCaseOrder[] =
+ {
+ 99, 97, 115, 101, 45, 111, 114, 100, 101, 114, 0
+ };
+ data = staticallyStoredCaseOrder;
+ length = 10;
+ break;
+ }
+
+ case CdataSectionElements:
+ {
+ static const unsigned short staticallyStoredCdataSectionElements[] =
+ {
+ 99, 100, 97, 116, 97, 45, 115, 101, 99, 116, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 115, 0
+ };
+ data = staticallyStoredCdataSectionElements;
+ length = 22;
+ break;
+ }
+
+ case Choose:
+ {
+ static const unsigned short staticallyStoredChoose[] =
+ {
+ 99, 104, 111, 111, 115, 101, 0
+ };
+ data = staticallyStoredChoose;
+ length = 6;
+ break;
+ }
+
+ case Collation:
+ {
+ static const unsigned short staticallyStoredCollation[] =
+ {
+ 99, 111, 108, 108, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredCollation;
+ length = 9;
+ break;
+ }
+
+ case Comment:
+ {
+ static const unsigned short staticallyStoredComment[] =
+ {
+ 99, 111, 109, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredComment;
+ length = 7;
+ break;
+ }
+
+ case Copy:
+ {
+ static const unsigned short staticallyStoredCopy[] =
+ {
+ 99, 111, 112, 121, 0
+ };
+ data = staticallyStoredCopy;
+ length = 4;
+ break;
+ }
+
+ case CopyNamespaces:
+ {
+ static const unsigned short staticallyStoredCopyNamespaces[] =
+ {
+ 99, 111, 112, 121, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115, 0
+ };
+ data = staticallyStoredCopyNamespaces;
+ length = 15;
+ break;
+ }
+
+ case CopyOf:
+ {
+ static const unsigned short staticallyStoredCopyOf[] =
+ {
+ 99, 111, 112, 121, 45, 111, 102, 0
+ };
+ data = staticallyStoredCopyOf;
+ length = 7;
+ break;
+ }
+
+ case DataType:
+ {
+ static const unsigned short staticallyStoredDataType[] =
+ {
+ 100, 97, 116, 97, 45, 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredDataType;
+ length = 9;
+ break;
+ }
+
+ case DefaultCollation:
+ {
+ static const unsigned short staticallyStoredDefaultCollation[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 45, 99, 111, 108, 108, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredDefaultCollation;
+ length = 17;
+ break;
+ }
+
+ case DefaultValidation:
+ {
+ static const unsigned short staticallyStoredDefaultValidation[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 45, 118, 97, 108, 105, 100, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredDefaultValidation;
+ length = 18;
+ break;
+ }
+
+ case DoctypePublic:
+ {
+ static const unsigned short staticallyStoredDoctypePublic[] =
+ {
+ 100, 111, 99, 116, 121, 112, 101, 45, 112, 117, 98, 108, 105, 99, 0
+ };
+ data = staticallyStoredDoctypePublic;
+ length = 14;
+ break;
+ }
+
+ case DoctypeSystem:
+ {
+ static const unsigned short staticallyStoredDoctypeSystem[] =
+ {
+ 100, 111, 99, 116, 121, 112, 101, 45, 115, 121, 115, 116, 101, 109, 0
+ };
+ data = staticallyStoredDoctypeSystem;
+ length = 14;
+ break;
+ }
+
+ case Document:
+ {
+ static const unsigned short staticallyStoredDocument[] =
+ {
+ 100, 111, 99, 117, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredDocument;
+ length = 8;
+ break;
+ }
+
+ case Element:
+ {
+ static const unsigned short staticallyStoredElement[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredElement;
+ length = 7;
+ break;
+ }
+
+ case Elements:
+ {
+ static const unsigned short staticallyStoredElements[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 115, 0
+ };
+ data = staticallyStoredElements;
+ length = 8;
+ break;
+ }
+
+ case Encoding:
+ {
+ static const unsigned short staticallyStoredEncoding[] =
+ {
+ 101, 110, 99, 111, 100, 105, 110, 103, 0
+ };
+ data = staticallyStoredEncoding;
+ length = 8;
+ break;
+ }
+
+ case EscapeUriAttributes:
+ {
+ static const unsigned short staticallyStoredEscapeUriAttributes[] =
+ {
+ 101, 115, 99, 97, 112, 101, 45, 117, 114, 105, 45, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115, 0
+ };
+ data = staticallyStoredEscapeUriAttributes;
+ length = 21;
+ break;
+ }
+
+ case ExcludeResultPrefixes:
+ {
+ static const unsigned short staticallyStoredExcludeResultPrefixes[] =
+ {
+ 101, 120, 99, 108, 117, 100, 101, 45, 114, 101, 115, 117, 108, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115, 0
+ };
+ data = staticallyStoredExcludeResultPrefixes;
+ length = 23;
+ break;
+ }
+
+ case ExtensionElementPrefixes:
+ {
+ static const unsigned short staticallyStoredExtensionElementPrefixes[] =
+ {
+ 101, 120, 116, 101, 110, 115, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115, 0
+ };
+ data = staticallyStoredExtensionElementPrefixes;
+ length = 26;
+ break;
+ }
+
+ case Flags:
+ {
+ static const unsigned short staticallyStoredFlags[] =
+ {
+ 102, 108, 97, 103, 115, 0
+ };
+ data = staticallyStoredFlags;
+ length = 5;
+ break;
+ }
+
+ case ForEach:
+ {
+ static const unsigned short staticallyStoredForEach[] =
+ {
+ 102, 111, 114, 45, 101, 97, 99, 104, 0
+ };
+ data = staticallyStoredForEach;
+ length = 8;
+ break;
+ }
+
+ case Format:
+ {
+ static const unsigned short staticallyStoredFormat[] =
+ {
+ 102, 111, 114, 109, 97, 116, 0
+ };
+ data = staticallyStoredFormat;
+ length = 6;
+ break;
+ }
+
+ case Function:
+ {
+ static const unsigned short staticallyStoredFunction[] =
+ {
+ 102, 117, 110, 99, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredFunction;
+ length = 8;
+ break;
+ }
+
+ case Href:
+ {
+ static const unsigned short staticallyStoredHref[] =
+ {
+ 104, 114, 101, 102, 0
+ };
+ data = staticallyStoredHref;
+ length = 4;
+ break;
+ }
+
+ case Id:
+ {
+ static const unsigned short staticallyStoredId[] =
+ {
+ 105, 100, 0
+ };
+ data = staticallyStoredId;
+ length = 2;
+ break;
+ }
+
+ case If:
+ {
+ static const unsigned short staticallyStoredIf[] =
+ {
+ 105, 102, 0
+ };
+ data = staticallyStoredIf;
+ length = 2;
+ break;
+ }
+
+ case Import:
+ {
+ static const unsigned short staticallyStoredImport[] =
+ {
+ 105, 109, 112, 111, 114, 116, 0
+ };
+ data = staticallyStoredImport;
+ length = 6;
+ break;
+ }
+
+ case ImportSchema:
+ {
+ static const unsigned short staticallyStoredImportSchema[] =
+ {
+ 105, 109, 112, 111, 114, 116, 45, 115, 99, 104, 101, 109, 97, 0
+ };
+ data = staticallyStoredImportSchema;
+ length = 13;
+ break;
+ }
+
+ case Include:
+ {
+ static const unsigned short staticallyStoredInclude[] =
+ {
+ 105, 110, 99, 108, 117, 100, 101, 0
+ };
+ data = staticallyStoredInclude;
+ length = 7;
+ break;
+ }
+
+ case IncludeContentType:
+ {
+ static const unsigned short staticallyStoredIncludeContentType[] =
+ {
+ 105, 110, 99, 108, 117, 100, 101, 45, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredIncludeContentType;
+ length = 20;
+ break;
+ }
+
+ case Indent:
+ {
+ static const unsigned short staticallyStoredIndent[] =
+ {
+ 105, 110, 100, 101, 110, 116, 0
+ };
+ data = staticallyStoredIndent;
+ length = 6;
+ break;
+ }
+
+ case InheritNamespaces:
+ {
+ static const unsigned short staticallyStoredInheritNamespaces[] =
+ {
+ 105, 110, 104, 101, 114, 105, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115, 0
+ };
+ data = staticallyStoredInheritNamespaces;
+ length = 18;
+ break;
+ }
+
+ case InputTypeAnnotations:
+ {
+ static const unsigned short staticallyStoredInputTypeAnnotations[] =
+ {
+ 105, 110, 112, 117, 116, 45, 116, 121, 112, 101, 45, 97, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 0
+ };
+ data = staticallyStoredInputTypeAnnotations;
+ length = 22;
+ break;
+ }
+
+ case Key:
+ {
+ static const unsigned short staticallyStoredKey[] =
+ {
+ 107, 101, 121, 0
+ };
+ data = staticallyStoredKey;
+ length = 3;
+ break;
+ }
+
+ case Lang:
+ {
+ static const unsigned short staticallyStoredLang[] =
+ {
+ 108, 97, 110, 103, 0
+ };
+ data = staticallyStoredLang;
+ length = 4;
+ break;
+ }
+
+ case Match:
+ {
+ static const unsigned short staticallyStoredMatch[] =
+ {
+ 109, 97, 116, 99, 104, 0
+ };
+ data = staticallyStoredMatch;
+ length = 5;
+ break;
+ }
+
+ case MatchingSubstring:
+ {
+ static const unsigned short staticallyStoredMatchingSubstring[] =
+ {
+ 109, 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103, 0
+ };
+ data = staticallyStoredMatchingSubstring;
+ length = 18;
+ break;
+ }
+
+ case MediaType:
+ {
+ static const unsigned short staticallyStoredMediaType[] =
+ {
+ 109, 101, 100, 105, 97, 45, 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredMediaType;
+ length = 10;
+ break;
+ }
+
+ case Message:
+ {
+ static const unsigned short staticallyStoredMessage[] =
+ {
+ 109, 101, 115, 115, 97, 103, 101, 0
+ };
+ data = staticallyStoredMessage;
+ length = 7;
+ break;
+ }
+
+ case Method:
+ {
+ static const unsigned short staticallyStoredMethod[] =
+ {
+ 109, 101, 116, 104, 111, 100, 0
+ };
+ data = staticallyStoredMethod;
+ length = 6;
+ break;
+ }
+
+ case Mode:
+ {
+ static const unsigned short staticallyStoredMode[] =
+ {
+ 109, 111, 100, 101, 0
+ };
+ data = staticallyStoredMode;
+ length = 4;
+ break;
+ }
+
+ case Name:
+ {
+ static const unsigned short staticallyStoredName[] =
+ {
+ 110, 97, 109, 101, 0
+ };
+ data = staticallyStoredName;
+ length = 4;
+ break;
+ }
+
+ case Namespace:
+ {
+ static const unsigned short staticallyStoredNamespace[] =
+ {
+ 110, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredNamespace;
+ length = 9;
+ break;
+ }
+
+ case NonMatchingSubstring:
+ {
+ static const unsigned short staticallyStoredNonMatchingSubstring[] =
+ {
+ 110, 111, 110, 45, 109, 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103, 0
+ };
+ data = staticallyStoredNonMatchingSubstring;
+ length = 22;
+ break;
+ }
+
+ case NormalizationForm:
+ {
+ static const unsigned short staticallyStoredNormalizationForm[] =
+ {
+ 110, 111, 114, 109, 97, 108, 105, 122, 97, 116, 105, 111, 110, 45, 102, 111, 114, 109, 0
+ };
+ data = staticallyStoredNormalizationForm;
+ length = 18;
+ break;
+ }
+
+ case OmitXmlDeclaration:
+ {
+ static const unsigned short staticallyStoredOmitXmlDeclaration[] =
+ {
+ 111, 109, 105, 116, 45, 120, 109, 108, 45, 100, 101, 99, 108, 97, 114, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredOmitXmlDeclaration;
+ length = 20;
+ break;
+ }
+
+ case Order:
+ {
+ static const unsigned short staticallyStoredOrder[] =
+ {
+ 111, 114, 100, 101, 114, 0
+ };
+ data = staticallyStoredOrder;
+ length = 5;
+ break;
+ }
+
+ case Otherwise:
+ {
+ static const unsigned short staticallyStoredOtherwise[] =
+ {
+ 111, 116, 104, 101, 114, 119, 105, 115, 101, 0
+ };
+ data = staticallyStoredOtherwise;
+ length = 9;
+ break;
+ }
+
+ case Output:
+ {
+ static const unsigned short staticallyStoredOutput[] =
+ {
+ 111, 117, 116, 112, 117, 116, 0
+ };
+ data = staticallyStoredOutput;
+ length = 6;
+ break;
+ }
+
+ case OutputVersion:
+ {
+ static const unsigned short staticallyStoredOutputVersion[] =
+ {
+ 111, 117, 116, 112, 117, 116, 45, 118, 101, 114, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredOutputVersion;
+ length = 14;
+ break;
+ }
+
+ case Override:
+ {
+ static const unsigned short staticallyStoredOverride[] =
+ {
+ 111, 118, 101, 114, 114, 105, 100, 101, 0
+ };
+ data = staticallyStoredOverride;
+ length = 8;
+ break;
+ }
+
+ case Param:
+ {
+ static const unsigned short staticallyStoredParam[] =
+ {
+ 112, 97, 114, 97, 109, 0
+ };
+ data = staticallyStoredParam;
+ length = 5;
+ break;
+ }
+
+ case PerformSort:
+ {
+ static const unsigned short staticallyStoredPerformSort[] =
+ {
+ 112, 101, 114, 102, 111, 114, 109, 45, 115, 111, 114, 116, 0
+ };
+ data = staticallyStoredPerformSort;
+ length = 12;
+ break;
+ }
+
+ case PreserveSpace:
+ {
+ static const unsigned short staticallyStoredPreserveSpace[] =
+ {
+ 112, 114, 101, 115, 101, 114, 118, 101, 45, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredPreserveSpace;
+ length = 14;
+ break;
+ }
+
+ case Priority:
+ {
+ static const unsigned short staticallyStoredPriority[] =
+ {
+ 112, 114, 105, 111, 114, 105, 116, 121, 0
+ };
+ data = staticallyStoredPriority;
+ length = 8;
+ break;
+ }
+
+ case ProcessingInstruction:
+ {
+ static const unsigned short staticallyStoredProcessingInstruction[] =
+ {
+ 112, 114, 111, 99, 101, 115, 115, 105, 110, 103, 45, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredProcessingInstruction;
+ length = 22;
+ break;
+ }
+
+ case Regex:
+ {
+ static const unsigned short staticallyStoredRegex[] =
+ {
+ 114, 101, 103, 101, 120, 0
+ };
+ data = staticallyStoredRegex;
+ length = 5;
+ break;
+ }
+
+ case Required:
+ {
+ static const unsigned short staticallyStoredRequired[] =
+ {
+ 114, 101, 113, 117, 105, 114, 101, 100, 0
+ };
+ data = staticallyStoredRequired;
+ length = 8;
+ break;
+ }
+
+ case ResultDocument:
+ {
+ static const unsigned short staticallyStoredResultDocument[] =
+ {
+ 114, 101, 115, 117, 108, 116, 45, 100, 111, 99, 117, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredResultDocument;
+ length = 15;
+ break;
+ }
+
+ case SchemaLocation:
+ {
+ static const unsigned short staticallyStoredSchemaLocation[] =
+ {
+ 115, 99, 104, 101, 109, 97, 45, 108, 111, 99, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredSchemaLocation;
+ length = 15;
+ break;
+ }
+
+ case Select:
+ {
+ static const unsigned short staticallyStoredSelect[] =
+ {
+ 115, 101, 108, 101, 99, 116, 0
+ };
+ data = staticallyStoredSelect;
+ length = 6;
+ break;
+ }
+
+ case Separator:
+ {
+ static const unsigned short staticallyStoredSeparator[] =
+ {
+ 115, 101, 112, 97, 114, 97, 116, 111, 114, 0
+ };
+ data = staticallyStoredSeparator;
+ length = 9;
+ break;
+ }
+
+ case Sequence:
+ {
+ static const unsigned short staticallyStoredSequence[] =
+ {
+ 115, 101, 113, 117, 101, 110, 99, 101, 0
+ };
+ data = staticallyStoredSequence;
+ length = 8;
+ break;
+ }
+
+ case Sort:
+ {
+ static const unsigned short staticallyStoredSort[] =
+ {
+ 115, 111, 114, 116, 0
+ };
+ data = staticallyStoredSort;
+ length = 4;
+ break;
+ }
+
+ case Stable:
+ {
+ static const unsigned short staticallyStoredStable[] =
+ {
+ 115, 116, 97, 98, 108, 101, 0
+ };
+ data = staticallyStoredStable;
+ length = 6;
+ break;
+ }
+
+ case Standalone:
+ {
+ static const unsigned short staticallyStoredStandalone[] =
+ {
+ 115, 116, 97, 110, 100, 97, 108, 111, 110, 101, 0
+ };
+ data = staticallyStoredStandalone;
+ length = 10;
+ break;
+ }
+
+ case StripSpace:
+ {
+ static const unsigned short staticallyStoredStripSpace[] =
+ {
+ 115, 116, 114, 105, 112, 45, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredStripSpace;
+ length = 11;
+ break;
+ }
+
+ case Stylesheet:
+ {
+ static const unsigned short staticallyStoredStylesheet[] =
+ {
+ 115, 116, 121, 108, 101, 115, 104, 101, 101, 116, 0
+ };
+ data = staticallyStoredStylesheet;
+ length = 10;
+ break;
+ }
+
+ case Template:
+ {
+ static const unsigned short staticallyStoredTemplate[] =
+ {
+ 116, 101, 109, 112, 108, 97, 116, 101, 0
+ };
+ data = staticallyStoredTemplate;
+ length = 8;
+ break;
+ }
+
+ case Terminate:
+ {
+ static const unsigned short staticallyStoredTerminate[] =
+ {
+ 116, 101, 114, 109, 105, 110, 97, 116, 101, 0
+ };
+ data = staticallyStoredTerminate;
+ length = 9;
+ break;
+ }
+
+ case Test:
+ {
+ static const unsigned short staticallyStoredTest[] =
+ {
+ 116, 101, 115, 116, 0
+ };
+ data = staticallyStoredTest;
+ length = 4;
+ break;
+ }
+
+ case Text:
+ {
+ static const unsigned short staticallyStoredText[] =
+ {
+ 116, 101, 120, 116, 0
+ };
+ data = staticallyStoredText;
+ length = 4;
+ break;
+ }
+
+ case Transform:
+ {
+ static const unsigned short staticallyStoredTransform[] =
+ {
+ 116, 114, 97, 110, 115, 102, 111, 114, 109, 0
+ };
+ data = staticallyStoredTransform;
+ length = 9;
+ break;
+ }
+
+ case Tunnel:
+ {
+ static const unsigned short staticallyStoredTunnel[] =
+ {
+ 116, 117, 110, 110, 101, 108, 0
+ };
+ data = staticallyStoredTunnel;
+ length = 6;
+ break;
+ }
+
+ case Type:
+ {
+ static const unsigned short staticallyStoredType[] =
+ {
+ 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredType;
+ length = 4;
+ break;
+ }
+
+ case UndeclarePrefixes:
+ {
+ static const unsigned short staticallyStoredUndeclarePrefixes[] =
+ {
+ 117, 110, 100, 101, 99, 108, 97, 114, 101, 45, 112, 114, 101, 102, 105, 120, 101, 115, 0
+ };
+ data = staticallyStoredUndeclarePrefixes;
+ length = 18;
+ break;
+ }
+
+ case Use:
+ {
+ static const unsigned short staticallyStoredUse[] =
+ {
+ 117, 115, 101, 0
+ };
+ data = staticallyStoredUse;
+ length = 3;
+ break;
+ }
+
+ case UseAttributeSets:
+ {
+ static const unsigned short staticallyStoredUseAttributeSets[] =
+ {
+ 117, 115, 101, 45, 97, 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116, 115, 0
+ };
+ data = staticallyStoredUseAttributeSets;
+ length = 18;
+ break;
+ }
+
+ case UseCharacterMaps:
+ {
+ static const unsigned short staticallyStoredUseCharacterMaps[] =
+ {
+ 117, 115, 101, 45, 99, 104, 97, 114, 97, 99, 116, 101, 114, 45, 109, 97, 112, 115, 0
+ };
+ data = staticallyStoredUseCharacterMaps;
+ length = 18;
+ break;
+ }
+
+ case UseWhen:
+ {
+ static const unsigned short staticallyStoredUseWhen[] =
+ {
+ 117, 115, 101, 45, 119, 104, 101, 110, 0
+ };
+ data = staticallyStoredUseWhen;
+ length = 8;
+ break;
+ }
+
+ case Validation:
+ {
+ static const unsigned short staticallyStoredValidation[] =
+ {
+ 118, 97, 108, 105, 100, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredValidation;
+ length = 10;
+ break;
+ }
+
+ case ValueOf:
+ {
+ static const unsigned short staticallyStoredValueOf[] =
+ {
+ 118, 97, 108, 117, 101, 45, 111, 102, 0
+ };
+ data = staticallyStoredValueOf;
+ length = 8;
+ break;
+ }
+
+ case Variable:
+ {
+ static const unsigned short staticallyStoredVariable[] =
+ {
+ 118, 97, 114, 105, 97, 98, 108, 101, 0
+ };
+ data = staticallyStoredVariable;
+ length = 8;
+ break;
+ }
+
+ case Version:
+ {
+ static const unsigned short staticallyStoredVersion[] =
+ {
+ 118, 101, 114, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredVersion;
+ length = 7;
+ break;
+ }
+
+ case When:
+ {
+ static const unsigned short staticallyStoredWhen[] =
+ {
+ 119, 104, 101, 110, 0
+ };
+ data = staticallyStoredWhen;
+ length = 4;
+ break;
+ }
+
+ case WithParam:
+ {
+ static const unsigned short staticallyStoredWithParam[] =
+ {
+ 119, 105, 116, 104, 45, 112, 97, 114, 97, 109, 0
+ };
+ data = staticallyStoredWithParam;
+ length = 10;
+ break;
+ }
+
+ case XpathDefaultNamespace:
+ {
+ static const unsigned short staticallyStoredXpathDefaultNamespace[] =
+ {
+ 120, 112, 97, 116, 104, 45, 100, 101, 102, 97, 117, 108, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredXpathDefaultNamespace;
+ length = 23;
+ break;
+ }
+
+ default:
+ /* It's either the default token, or an undefined enum
+ * value. We silence a compiler warning, and return the
+ * empty string. */
+ ;
+ }
+
+ union
+ {
+ const unsigned short *data;
+ const QChar *asQChar;
+ } converter;
+ converter.data = data;
+
+ return QString::fromRawData(converter.asQChar, length);
+ }
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/parser/qxslttokenlookup.xml b/src/xmlpatterns/parser/qxslttokenlookup.xml
new file mode 100644
index 0000000..1972929
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tokenAutomaton scope="public"
+ className="XSLTTokenLookup"
+ headerFile="qxslttokenlookup_p.h"
+ sourceFile="qxslttokenlookup.cpp"
+ namespace="QPatternist"
+ defaultToken="NoKeyword"
+ hasToString="true"
+ tokenEnum="NodeName"
+ includeGuardName="qxslttokenlookup_p_H">
+ <tokens>
+ <token>analyze-string</token>
+ <token>apply-templates</token>
+ <token>as</token>
+ <token>attribute-set</token>
+ <token>attribute</token>
+ <token>byte-order-mark</token>
+ <token>call-template</token>
+ <token>case-order</token>
+ <token>cdata-section-elements</token>
+ <token>choose</token>
+ <token>collation</token>
+ <token>comment</token>
+ <token>copy-namespaces</token>
+ <token>copy-of</token>
+ <token>copy</token>
+ <token>data-type</token>
+ <token>default-collation</token>
+ <token>default-validation</token>
+ <token>doctype-public</token>
+ <token>doctype-system</token>
+ <token>document</token>
+ <token>elements</token>
+ <token>element</token>
+ <token>encoding</token>
+ <token>escape-uri-attributes</token>
+ <token>exclude-result-prefixes</token>
+ <token>extension-element-prefixes</token>
+ <token>flags</token>
+ <token>for-each</token>
+ <token>format</token>
+ <token>function</token>
+ <token>href</token>
+ <token>id</token>
+ <token>if</token>
+ <token>import-schema</token>
+ <token>import</token>
+ <token>include-content-type</token>
+ <token>include</token>
+ <token>indent</token>
+ <token>inherit-namespaces</token>
+ <token>input-type-annotations</token>
+ <token>key</token>
+ <token>lang</token>
+ <token>matching-substring</token>
+ <token>match</token>
+ <token>media-type</token>
+ <token>message</token>
+ <token>method</token>
+ <token>mode</token>
+ <token>namespace</token>
+ <token>name</token>
+ <token>non-matching-substring</token>
+ <token>normalization-form</token>
+ <token>omit-xml-declaration</token>
+ <token>order</token>
+ <token>otherwise</token>
+ <token>output</token>
+ <token>output-version</token>
+ <token>override</token>
+ <token>param</token>
+ <token>perform-sort</token>
+ <token>preserve-space</token>
+ <token>priority</token>
+ <token>processing-instruction</token>
+ <token>regex</token>
+ <token>required</token>
+ <token>result-document</token>
+ <token>schema-location</token>
+ <token>select</token>
+ <token>separator</token>
+ <token>sequence</token>
+ <token>sort</token>
+ <token>stable</token>
+ <token>standalone</token>
+ <token>strip-space</token>
+ <token>stylesheet</token>
+ <token>template</token>
+ <token>terminate</token>
+ <token>test</token>
+ <token>text</token>
+ <token>transform</token>
+ <token>tunnel</token>
+ <token>type</token>
+ <token>undeclare-prefixes</token>
+ <token>use-attribute-sets</token>
+ <token>use-character-maps</token>
+ <token>use</token>
+ <token>use-when</token>
+ <token>validation</token>
+ <token>value-of</token>
+ <token>variable</token>
+ <token>version</token>
+ <token>when</token>
+ <token>with-param</token>
+ <token>xpath-default-namespace</token>
+ </tokens>
+
+ <boilerplate>
+
+ <prolog>/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+//
+
+</prolog>
+
+ </boilerplate>
+
+</tokenAutomaton>
diff --git a/src/xmlpatterns/parser/qxslttokenlookup_p.h b/src/xmlpatterns/parser/qxslttokenlookup_p.h
new file mode 100644
index 0000000..3e65965
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+//
+
+/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */
+
+#ifndef qxslttokenlookup_p_H
+#define qxslttokenlookup_p_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class XSLTTokenLookup
+ {
+ public:
+ enum NodeName
+
+ {
+ NoKeyword,
+ AnalyzeString,
+ ApplyTemplates,
+ As,
+ Attribute,
+ AttributeSet,
+ ByteOrderMark,
+ CallTemplate,
+ CaseOrder,
+ CdataSectionElements,
+ Choose,
+ Collation,
+ Comment,
+ Copy,
+ CopyNamespaces,
+ CopyOf,
+ DataType,
+ DefaultCollation,
+ DefaultValidation,
+ DoctypePublic,
+ DoctypeSystem,
+ Document,
+ Element,
+ Elements,
+ Encoding,
+ EscapeUriAttributes,
+ ExcludeResultPrefixes,
+ ExtensionElementPrefixes,
+ Flags,
+ ForEach,
+ Format,
+ Function,
+ Href,
+ Id,
+ If,
+ Import,
+ ImportSchema,
+ Include,
+ IncludeContentType,
+ Indent,
+ InheritNamespaces,
+ InputTypeAnnotations,
+ Key,
+ Lang,
+ Match,
+ MatchingSubstring,
+ MediaType,
+ Message,
+ Method,
+ Mode,
+ Name,
+ Namespace,
+ NonMatchingSubstring,
+ NormalizationForm,
+ OmitXmlDeclaration,
+ Order,
+ Otherwise,
+ Output,
+ OutputVersion,
+ Override,
+ Param,
+ PerformSort,
+ PreserveSpace,
+ Priority,
+ ProcessingInstruction,
+ Regex,
+ Required,
+ ResultDocument,
+ SchemaLocation,
+ Select,
+ Separator,
+ Sequence,
+ Sort,
+ Stable,
+ Standalone,
+ StripSpace,
+ Stylesheet,
+ Template,
+ Terminate,
+ Test,
+ Text,
+ Transform,
+ Tunnel,
+ Type,
+ UndeclarePrefixes,
+ Use,
+ UseAttributeSets,
+ UseCharacterMaps,
+ UseWhen,
+ Validation,
+ ValueOf,
+ Variable,
+ Version,
+ When,
+ WithParam,
+ XpathDefaultNamespace
+ };
+
+ static inline NodeName toToken(const QString &value);
+ static inline NodeName toToken(const QStringRef &value);
+ static NodeName toToken(const QChar *data, int length);
+ static QString toString(NodeName token);
+
+
+ private:
+ static inline NodeName classifier2(const QChar *data);
+ static inline NodeName classifier3(const QChar *data);
+ static inline NodeName classifier4(const QChar *data);
+ static inline NodeName classifier5(const QChar *data);
+ static inline NodeName classifier6(const QChar *data);
+ static inline NodeName classifier7(const QChar *data);
+ static inline NodeName classifier8(const QChar *data);
+ static inline NodeName classifier9(const QChar *data);
+ static inline NodeName classifier10(const QChar *data);
+ static inline NodeName classifier11(const QChar *data);
+ static inline NodeName classifier12(const QChar *data);
+ static inline NodeName classifier13(const QChar *data);
+ static inline NodeName classifier14(const QChar *data);
+ static inline NodeName classifier15(const QChar *data);
+ static inline NodeName classifier17(const QChar *data);
+ static inline NodeName classifier18(const QChar *data);
+ static inline NodeName classifier20(const QChar *data);
+ static inline NodeName classifier21(const QChar *data);
+ static inline NodeName classifier22(const QChar *data);
+ static inline NodeName classifier23(const QChar *data);
+ static inline NodeName classifier26(const QChar *data);
+
+ };
+
+ inline XSLTTokenLookup::NodeName XSLTTokenLookup::toToken(const QString &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+ inline XSLTTokenLookup::NodeName XSLTTokenLookup::toToken(const QStringRef &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/xmlpatterns/parser/trolltechHeader.txt b/src/xmlpatterns/parser/trolltechHeader.txt
new file mode 100644
index 0000000..8ac086a
--- /dev/null
+++ b/src/xmlpatterns/parser/trolltechHeader.txt
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
diff --git a/src/xmlpatterns/parser/winCEWorkaround.sed b/src/xmlpatterns/parser/winCEWorkaround.sed
new file mode 100644
index 0000000..46f18ae
--- /dev/null
+++ b/src/xmlpatterns/parser/winCEWorkaround.sed
@@ -0,0 +1,32 @@
+/\/\* Tokens\. \*\// i\
+\/\* These tokens are defined to nothing on Windows because they\'re\
+ \* used in their documentation parser, for use in things like:\
+ \*\
+ \* int foo(IN char\* name, OUT char\* path);\
+ \*\
+ \* Hence this un-break fix. Note that this file was auto generated. *\/\
+\#ifdef IN\
+\# undef IN\
+\#endif\
+\#ifdef INSTANCE\
+\# undef INSTANCE\
+\#endif\
+\#ifdef STRICT\
+\# undef STRICT\
+\#endif\
+\#ifdef SELF\
+\# undef SELF\
+\#endif\
+\/\* These tokens are defined in VxWorks kernel mode\
+ \*\
+ \* Hence this un-break fix. Note that this file was auto generated. *\/\
+\#ifdef ERROR\
+\# undef ERROR\
+\#endif\
+\#ifdef IMPORT\
+\# undef IMPORT\
+\#endif\
+\#ifdef MAP\
+\# undef MAP\
+\#endif\
+
diff --git a/src/xmlpatterns/projection/projection.pri b/src/xmlpatterns/projection/projection.pri
new file mode 100644
index 0000000..530041d
--- /dev/null
+++ b/src/xmlpatterns/projection/projection.pri
@@ -0,0 +1,4 @@
+SOURCES += $$PWD/qdocumentprojector.cpp
+
+HEADERS += $$PWD/qdocumentprojector_p.h \
+ $$PWD/qprojectedexpression_p.h
diff --git a/src/xmlpatterns/projection/qdocumentprojector.cpp b/src/xmlpatterns/projection/qdocumentprojector.cpp
new file mode 100644
index 0000000..b3b5927
--- /dev/null
+++ b/src/xmlpatterns/projection/qdocumentprojector.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdocumentprojector_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DocumentProjector::DocumentProjector(const ProjectedExpression::Vector &paths,
+ QAbstractXmlReceiver *const receiver) : m_paths(paths)
+ , m_pathCount(paths.count())
+ , m_action(ProjectedExpression::Move)
+ , m_nodesInProcess(0)
+ , m_receiver(receiver)
+{
+ Q_ASSERT_X(paths.count() > 0, Q_FUNC_INFO,
+ "Using DocumentProjector with no paths is an "
+ "overhead and has also undefined behavior.");
+ Q_ASSERT(m_receiver);
+}
+
+void DocumentProjector::startElement(const QXmlName name)
+{
+ Q_UNUSED(name);
+
+ switch(m_action)
+ {
+ case ProjectedExpression::KeepSubtree:
+ {
+ m_receiver->startElement(name);
+ /* Fallthrough. */
+ }
+ case ProjectedExpression::Skip:
+ {
+ ++m_nodesInProcess;
+ return;
+ }
+ default:
+ {
+ Q_ASSERT_X(m_action == ProjectedExpression::Move, Q_FUNC_INFO,
+ "We're not supposed to receive Keep here, because "
+ "endElement() should always end that state.");
+
+ for(int i = 0; i < m_pathCount; ++i)
+ {
+ m_action = m_paths.at(i)->actionForElement(name, m_paths[i]);
+
+ switch(m_action)
+ {
+ case ProjectedExpression::Keep:
+ {
+ m_action = ProjectedExpression::Keep;
+ continue;
+ }
+ case ProjectedExpression::KeepSubtree:
+ {
+ /* Ok, at least one path wanted this node. Pass it on,
+ * and exit. */
+ m_receiver->startElement(name);
+ ++m_nodesInProcess;
+ return;
+ }
+ case ProjectedExpression::Skip:
+ {
+ /* This particular path doesn't need it, but
+ * some other path might, so continue looping. */
+ continue;
+ }
+ case ProjectedExpression::Move:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "The action functions can never return Move.");
+ }
+ }
+
+ ++m_nodesInProcess;
+
+ if(m_action == ProjectedExpression::Keep)
+ m_receiver->startElement(name);
+ else
+ {
+ Q_ASSERT(m_action == ProjectedExpression::Skip);
+ }
+ }
+ }
+}
+
+void DocumentProjector::endElement()
+{
+ if(m_action == ProjectedExpression::Keep)
+ {
+ Q_ASSERT(m_nodesInProcess == 1);
+
+ m_receiver->endElement();
+
+ /* We have now kept the single node, and now wants to skip
+ * all its children. */
+ m_action = ProjectedExpression::Skip;
+ m_nodesInProcess = 0;
+ }
+ else if(m_action == ProjectedExpression::KeepSubtree)
+ {
+ m_receiver->endElement();
+ --m_nodesInProcess;
+
+ if(m_nodesInProcess == 0)
+ {
+ /* We have now skipped all the children, let's do
+ * a new path analysis. */
+ m_action = ProjectedExpression::Move;
+ }
+ }
+ else
+ {
+ Q_ASSERT_X(m_action == ProjectedExpression::Skip, Q_FUNC_INFO,
+ "We're not supposed to be in a Move action here.");
+ /* We skip calling m_receiver's endElement() here since we're
+ * skipping. */
+ Q_ASSERT(m_nodesInProcess > 0);
+ --m_nodesInProcess;
+
+ if(m_nodesInProcess == 0)
+ {
+ /* Ok, we've skipped them all, let's do something
+ * new -- let's Move on to the next path! */
+ m_action = ProjectedExpression::Move;
+ }
+ }
+}
+
+void DocumentProjector::attribute(const QXmlName name,
+ const QString &value)
+{
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+}
+
+void DocumentProjector::namespaceBinding(const QXmlName nb)
+{
+ Q_UNUSED(nb);
+}
+
+void DocumentProjector::comment(const QString &value)
+{
+ Q_ASSERT_X(!value.contains(QLatin1String("--")), Q_FUNC_INFO,
+ "Invalid input; it's the caller's responsibility to ensure the input is correct.");
+ Q_UNUSED(value);
+}
+
+void DocumentProjector::characters(const QString &value)
+{
+ Q_UNUSED(value);
+}
+
+void DocumentProjector::processingInstruction(const QXmlName name,
+ const QString &value)
+{
+ Q_ASSERT_X(!value.contains(QLatin1String("?>")), Q_FUNC_INFO,
+ "Invalid input; it's the caller's responsibility to ensure the input is correct.");
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+}
+
+void DocumentProjector::item(const Item &outputItem)
+{
+ Q_UNUSED(outputItem);
+}
+
+void DocumentProjector::startDocument()
+{
+}
+
+void DocumentProjector::endDocument()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/projection/qdocumentprojector_p.h b/src/xmlpatterns/projection/qdocumentprojector_p.h
new file mode 100644
index 0000000..d5f665d
--- /dev/null
+++ b/src/xmlpatterns/projection/qdocumentprojector_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DocumentProjector_H
+#define Patternist_DocumentProjector_H
+
+#include "qprojectedexpression_p.h"
+#include "qabstractxmlreceiver.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DocumentProjector : public QAbstractXmlReceiver
+ {
+ public:
+ DocumentProjector(const ProjectedExpression::Vector &paths,
+ QAbstractXmlReceiver *const receiver);
+
+ virtual void namespaceBinding(const QXmlName nb);
+
+ virtual void characters(const QString &value);
+ virtual void comment(const QString &value);
+
+ virtual void startElement(const QXmlName name);
+
+ virtual void endElement();
+
+ virtual void attribute(const QXmlName name,
+ const QString &value);
+
+ virtual void processingInstruction(const QXmlName name,
+ const QString &value);
+
+ virtual void item(const Item &item);
+
+ virtual void startDocument();
+ virtual void endDocument();
+
+ ProjectedExpression::Vector m_paths;
+ const int m_pathCount;
+ ProjectedExpression::Action m_action;
+ int m_nodesInProcess;
+ QAbstractXmlReceiver *const m_receiver;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/projection/qprojectedexpression_p.h b/src/xmlpatterns/projection/qprojectedexpression_p.h
new file mode 100644
index 0000000..8a2b2e0
--- /dev/null
+++ b/src/xmlpatterns/projection/qprojectedexpression_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ProjectedExpression_H
+#define Patternist_ProjectedExpression_H
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ProjectedExpression
+ {
+ public:
+ typedef ProjectedExpression * Ptr;
+ typedef QVector<ProjectedExpression::Ptr> Vector;
+ virtual ~ProjectedExpression()
+ {
+ }
+
+ enum Action
+ {
+ Move = 0,
+ Skip = 1,
+ Keep = 2,
+ KeepSubtree = 4 | Keep
+ };
+
+ virtual Action actionForElement(const QXmlName name,
+ ProjectedExpression::Ptr &next) const
+ {
+ Q_UNUSED(name);
+ Q_UNUSED(next);
+ return Skip;
+ }
+
+ };
+
+ class ProjectedNodeTest
+ {
+ public:
+ typedef ProjectedNodeTest * Ptr;
+ virtual ~ProjectedNodeTest()
+ {
+ }
+
+ virtual bool isMatch(const QXmlNodeModelIndex::NodeKind kind) const
+ {
+ Q_UNUSED(kind);
+ return false;
+ }
+ };
+
+ class ProjectedStep : public ProjectedExpression
+ {
+ public:
+ ProjectedStep(const ProjectedNodeTest::Ptr test,
+ const QXmlNodeModelIndex::Axis axis) : m_test(test),
+ m_axis(axis)
+ {
+ Q_ASSERT(m_test);
+ }
+
+ virtual Action actionForElement(const QXmlName name,
+ ProjectedExpression::Ptr &next) const
+ {
+ Q_UNUSED(name);
+ Q_UNUSED(next);
+ // TODO
+ return Skip;
+ }
+
+ private:
+ const ProjectedNodeTest::Ptr m_test;
+ const QXmlNodeModelIndex::Axis m_axis;
+ };
+
+ class ProjectedPath : public ProjectedExpression
+ {
+ public:
+ ProjectedPath(const ProjectedExpression::Ptr left,
+ const ProjectedExpression::Ptr right) : m_left(left),
+ m_right(right)
+ {
+ Q_ASSERT(m_left);
+ Q_ASSERT(m_right);
+ }
+
+ virtual Action actionForElement(const QXmlName name,
+ ProjectedExpression::Ptr &next) const
+ {
+ ProjectedExpression::Ptr &candidateNext = next;
+ const Action a = m_left->actionForElement(name, candidateNext);
+
+ if(a != Skip)
+ {
+ /* The test accepted it, so let's replace us with the new step. */
+ next = candidateNext;
+ }
+
+ return a;
+ }
+
+ private:
+ const ProjectedExpression::Ptr m_left;
+ const ProjectedExpression::Ptr m_right;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/qtokenautomaton/README b/src/xmlpatterns/qtokenautomaton/README
new file mode 100644
index 0000000..8c5e552
--- /dev/null
+++ b/src/xmlpatterns/qtokenautomaton/README
@@ -0,0 +1,66 @@
+
+qtokenautomaton is a token generator, that generates a simple, Unicode aware
+tokenizer for C++ that uses the Qt API.
+
+Introduction
+=====================
+QTokenAutomaton generates a C++ class that essentially has this interface:
+
+ class YourTokenizer
+ {
+ protected:
+ enum Token
+ {
+ A,
+ B,
+ C,
+ NoKeyword
+ };
+
+ static inline Token toToken(const QString &string);
+ static inline Token toToken(const QStringRef &string);
+ static Token toToken(const QChar *data, int length);
+ static QString toString(Token token);
+ };
+
+When calling toToken(), the tokenizer returns the enum value corresponding to
+the string. This is done with O(N) time complexity, where N is the length of
+the string. The returned value can then subsequently be efficiently switched
+over. The alternatives, either a long chain of if statements comparing one
+QString to several other QStrings; or inserting all strings first into a hash,
+are less efficient.
+
+For instance, the latter case of using a hash would involve when excluding the
+initial populating of the hash, O(N) + O(1) where 0(1) is assumed to be a
+non-conflicting hash lookup.
+
+toString(), which returns the string for the token that an enum value
+represents, is implemented to store the strings in an efficient manner.
+
+A typical usage scenario is in combination with QXmlStreamReader. When parsing
+a certain format, for instance XHTML, each element name, body, span, table and
+so forth, typically needs special treatment. QTokenAutomaton conceptually cuts
+the string comparisons down to one.
+
+Beyond efficiency, QTokenAutomaton also increases type safety, since C++
+identifiers are used instead of string literals.
+
+Usage
+=====================
+Using it is approached as follows:
+
+1. Create a token file. Use exampleFile.xml as a template.
+
+2. Make sure it is valid by validating against qtokenautomaton.xsd. On
+ Linux, this can be achieved by running `xmllint --noout
+ --schema qtokenautomaton.xsd yourFile.xml`
+
+3. Produce the C++ files by invoking the stylesheet with an XSL-T 2.0
+ processor[1]. For instance, with the implementation Saxon, this would be:
+ `java net.sf.saxon.Transform -xsl:qautomaton2cpp.xsl yourFile.xml`
+
+4. Include the produced C++ files with your build system.
+
+
+1.
+In Qt there is as of 4.4 no support for XSL-T.
diff --git a/src/xmlpatterns/qtokenautomaton/exampleFile.xml b/src/xmlpatterns/qtokenautomaton/exampleFile.xml
new file mode 100644
index 0000000..1274443
--- /dev/null
+++ b/src/xmlpatterns/qtokenautomaton/exampleFile.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tokenAutomaton scope="public"
+ className="ExampleFile"
+ headerFile="exampleFile.h"
+ sourceFile="exampleFile.cpp"
+ defaultToken="NoKeyword"
+ tokenEnum="Token"
+ hasToString="true"
+ includeGuardName="exampleFile_h">
+ <tokens>
+ <token>html</token>
+ <token>body</token>
+ <token>p</token>
+ <token>table</token>
+ <token name="WeWantADifferentNameForSpan">span</token>
+ </tokens>
+
+ <boilerplate>
+
+ <prolog>/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+</prolog>
+
+ </boilerplate>
+
+</tokenAutomaton>
diff --git a/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl b/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl
new file mode 100644
index 0000000..16084a0
--- /dev/null
+++ b/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl
@@ -0,0 +1,298 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<xsl:stylesheet version="2.0"
+ xml:lang="en"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:local="http://www.w3.org/2005/xquery-local-functions"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xsl:variable name="className" as="xs:string" select="tokenAutomaton/@className"/>
+ <xsl:variable name="defaultToken" as="xs:string" select="tokenAutomaton/@defaultToken"/>
+ <xsl:variable name="tokens" as="element(token)+" select="tokenAutomaton/tokens/token"/>
+ <xsl:variable name="tokenEnum" as="xs:string" select="tokenAutomaton/@tokenEnum"/>
+
+ <xsl:variable name="warningGenerated" as="xs:string">/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */&#xA;</xsl:variable>
+
+ <xsl:template match="tokenAutomaton">
+
+ <xsl:variable name="uniqueLengths" as="xs:integer+" select="distinct-values(tokens/token/string-length())"/>
+
+ <xsl:result-document method="text" href="{@headerFile}">
+
+ <xsl:variable name="includeGuardName" select="string(@includeGuardName)"/>
+
+ <xsl:value-of select="boilerplate/prolog"/>
+
+ <xsl:value-of select="$warningGenerated"/>
+
+ <xsl:text>&#xA;#ifndef </xsl:text>
+ <xsl:value-of select="$includeGuardName"/>
+ <xsl:text>&#xA;#define </xsl:text>
+ <xsl:value-of select="$includeGuardName"/>
+ <xsl:text>&#xA;&#xA;</xsl:text>
+
+ <xsl:text>#include &lt;QtCore/QString>&#xA;</xsl:text>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:text>QT_BEGIN_NAMESPACE&#xA;</xsl:text>
+ <xsl:text>&#xA;</xsl:text>
+
+ <xsl:if test="@namespace">
+ <xsl:text>namespace </xsl:text>
+ <xsl:value-of select="@namespace"/>
+ {
+ </xsl:if>
+
+ <xsl:text>class </xsl:text>
+ <xsl:value-of select="@className"/>
+ {
+ <xsl:value-of select="@scope"/>:
+ <xsl:text>enum </xsl:text>
+ <xsl:value-of select="$tokenEnum"/>
+ <xsl:text>&#xA;</xsl:text>
+ {
+ <xsl:value-of separator=",&#xA;">
+ <xsl:sequence select="@defaultToken"/>
+ <xsl:perform-sort select="tokens/token/local:tokenToEnumName(.)">
+ <xsl:sort select="."/>
+ </xsl:perform-sort>
+ </xsl:value-of>
+ };
+
+ <xsl:text>static inline </xsl:text>
+ <xsl:value-of select="$tokenEnum"/>
+ <xsl:text> toToken(const QString &amp;value);&#xA;</xsl:text>
+ <xsl:text>static inline </xsl:text>
+ <xsl:value-of select="$tokenEnum"/>
+ <xsl:text> toToken(const QStringRef &amp;value);&#xA;</xsl:text>
+ <xsl:text>static </xsl:text>
+ <xsl:value-of select="$tokenEnum"/>
+ <xsl:text> toToken(const QChar *data, int length);&#xA;</xsl:text>
+ <xsl:if test="xs:boolean(@hasToString)">
+ <xsl:text>static QString toString(</xsl:text>
+ <xsl:value-of select="$tokenEnum"/>
+ <xsl:text> token);&#xA;</xsl:text>
+ </xsl:if>
+
+ private:
+ <xsl:for-each select="$uniqueLengths">
+ <xsl:sort select="."/>
+ <xsl:text>static inline </xsl:text>
+ <xsl:value-of select="$tokenEnum"/>
+ <xsl:text> classifier</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>(const QChar *data);&#xA;</xsl:text>
+ </xsl:for-each>
+ };
+
+ <xsl:text>inline </xsl:text>
+ <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@className"/>::toToken(const QString &amp;value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+ <xsl:text>inline </xsl:text>
+ <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@className"/>::toToken(const QStringRef &amp;value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+ <xsl:if test="@namespace">
+ <xsl:text>}&#xA;</xsl:text>
+ </xsl:if>
+
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:text>QT_END_NAMESPACE&#xA;</xsl:text>
+ <xsl:text>&#xA;</xsl:text>
+
+ <xsl:text>#endif&#xA;</xsl:text>
+ </xsl:result-document>
+
+ <xsl:result-document method="text" href="{@sourceFile}">
+ <xsl:value-of select="boilerplate/prolog"/>
+
+ <xsl:value-of select="$warningGenerated"/>
+
+ <xsl:text>&#xA;#include "</xsl:text>
+ <xsl:value-of select="@headerFile"/>
+ <xsl:text>"&#xA;</xsl:text>
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:text>QT_BEGIN_NAMESPACE&#xA;</xsl:text>
+
+ <xsl:if test="@namespace">
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:text>using namespace </xsl:text>
+ <xsl:value-of select="@namespace"/>
+ <xsl:text>;&#xA;</xsl:text>
+ </xsl:if>
+
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:variable name="tokens" select="tokens/token"/>
+
+ <xsl:for-each select="$uniqueLengths">
+ <xsl:sort select="."/>
+ <xsl:call-template name="generate-classifier">
+ <xsl:with-param name="strings" select="$tokens[string-length() eq current()]"/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@className"/>::toToken(const QChar *data, int length)
+ {
+ switch(length)
+ {
+ <xsl:for-each select="$uniqueLengths">
+ <xsl:sort data-type="number" select="."/>
+ case <xsl:value-of select="."/>:
+ return classifier<xsl:value-of select="."/>(data);
+
+ </xsl:for-each>
+ default:
+ return <xsl:value-of select="@defaultToken"/>;
+ }
+ }
+
+ <xsl:if test="xs:boolean(@hasToString)">
+ QString <xsl:value-of select="@className"/>::toString(<xsl:value-of select="$tokenEnum"/> token)
+ {
+ const unsigned short *data = 0;
+ int length = 0;
+
+ switch(token)
+ {
+ <xsl:for-each select="tokens/token">
+ <xsl:sort select="local:tokenToEnumName(.)"/>
+ case <xsl:sequence select="local:tokenToEnumName(.)"/>:
+ {<!-- Without these braces, the code doesn't compile on MSVC 2008. -->
+ static const unsigned short staticallyStored<xsl:value-of select="local:tokenToEnumName(.)"/>[] =
+ {
+ <xsl:value-of separator=", " select="string-to-codepoints(.), 0"/>
+ };
+ data = staticallyStored<xsl:value-of select="local:tokenToEnumName(.)"/>;
+ length = <xsl:value-of select="string-length(.)"/>;
+ break;
+ }
+ </xsl:for-each>
+ default:
+ /* It's either the default token, or an undefined enum
+ * value. We silence a compiler warning, and return the
+ * empty string. */
+ ;
+ }
+
+ union
+ {
+ const unsigned short *data;
+ const QChar *asQChar;
+ } converter;
+ converter.data = data;
+
+ return QString::fromRawData(converter.asQChar, length);
+ }
+ </xsl:if>
+
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:text>QT_END_NAMESPACE&#xA;</xsl:text>
+ <xsl:text>&#xA;</xsl:text>
+ </xsl:result-document>
+
+ </xsl:template>
+
+ <xsl:template name="generate-classifier">
+ <xsl:param name="strings" as="xs:string+"/>
+
+ <xsl:value-of select="$className"/>::<xsl:value-of select="$tokenEnum"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$className"/>::classifier<xsl:value-of select="."/>(const QChar *data)
+
+ {
+ <xsl:sequence select="local:generateBranching($strings, 1, 1)"/>
+
+ return <xsl:value-of select="$defaultToken"/>;
+ }
+ </xsl:template>
+
+ <xsl:function name="local:generateBranching" ><!--as="xs:string+">-->
+ <xsl:param name="strings" as="xs:string+"/>
+ <xsl:param name="depth" as="xs:integer"/>
+ <xsl:param name="currentPos" as="xs:integer"/>
+
+ <xsl:choose>
+ <xsl:when test="count($strings) eq 1">
+ <xsl:variable name="remainingLength" as="xs:integer" select="(string-length($strings) - $currentPos) + 1"/>
+ <xsl:variable name="toMatch" as="xs:integer+" select="string-to-codepoints(substring($strings, $currentPos))"/>
+
+ <xsl:if test="$remainingLength ne 0">
+ <xsl:choose>
+ <xsl:when test="$remainingLength eq 1">
+ if(data[<xsl:sequence select="$depth - 1"/>] == <xsl:sequence select="$toMatch"/>)
+ </xsl:when>
+ <xsl:when test="$remainingLength &gt; 1">
+ static const unsigned short string[] =
+ {
+ <xsl:value-of separator=", " select="string-to-codepoints(substring($strings, $currentPos))"/>
+ };
+ if(memcmp(&amp;data[<xsl:sequence select="$depth - 1"/>], &amp;string, sizeof(QChar) * <xsl:value-of select="$remainingLength"/>) == 0)
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ return <xsl:value-of select="local:tokenToEnumName($strings)"/>;
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="distinct-values(for $i in $strings return substring($i, $currentPos, 1))">
+ <xsl:if test="position() &gt; 1">
+ <xsl:text>else </xsl:text>
+ </xsl:if>
+
+ <xsl:text>if (data[</xsl:text>
+ <xsl:sequence select="string($depth - 1)"/>
+ <xsl:text>] == </xsl:text>
+ <xsl:sequence select="string-to-codepoints(.)"/>
+ <xsl:text>)&#xA;</xsl:text>
+
+ {
+ <xsl:sequence select="local:generateBranching($strings[substring(., $currentPos, 1) eq current()], $depth + 1, $currentPos + 1)"/>
+ }
+
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:function>
+
+ <xsl:function name="local:toCamelCase" as="xs:string">
+ <xsl:param name="arg" as="xs:string"/>
+
+ <xsl:sequence select="string-join((for $word in tokenize($arg,'[:-]+')
+ return concat(upper-case(substring($word,1,1)),
+ substring($word, 2))) ,'')"/>
+
+ </xsl:function>
+
+ <xsl:function name="local:tokenToEnumName" as="xs:string">
+ <xsl:param name="string" as="xs:string"/>
+
+ <xsl:variable name="token" select="$tokens[. eq $string]"/>
+
+ <xsl:choose>
+ <xsl:when test="$token/@name">
+ <xsl:sequence select="$token/@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- We take the token's string value, and coerces into a C++
+ name. So get rid of invalid characters. Also do basic camel casing. -->
+ <xsl:variable name="normalized" select="translate($string, 'ABCDEFGHIJKLMNOPQRSTYXZabcdefghijklmnopqrstyxz1234567890_', 'ABCDEFGHIJKLMNOPQRSTYXZabcdefghijklmnopqrstyxz1234567890_')"/>
+ <xsl:value-of select="local:toCamelCase($normalized)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:function>
+
+</xsl:stylesheet>
+
+<!--
+vim: et:ts=4:sw=4:sts=4
+-->
diff --git a/src/xmlpatterns/qtokenautomaton/qtokenautomaton.xsd b/src/xmlpatterns/qtokenautomaton/qtokenautomaton.xsd
new file mode 100644
index 0000000..322c50e
--- /dev/null
+++ b/src/xmlpatterns/qtokenautomaton/qtokenautomaton.xsd
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+TODO docs
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+ <xs:element name="tokenAutomaton" type="tokenAutomatonElementType"/>
+
+ <xs:simpleType name="cppIdentifierType">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[a-zA-Z_][a-zA-Z0-9_]*"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="filenameType">
+ <xs:restriction base="xs:string">
+ <!-- At least one character. -->
+ <xs:pattern value=".+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="scopeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="protected"/>
+ <xs:enumeration value="public"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="tokenAutomatonElementType">
+ <xs:sequence>
+ <xs:element name="tokens" minOccurs="1" maxOccurs="1" type="tokensElementType">
+ <!-- Each token name (the enum name), must be unique. -->
+ <xs:unique name="tokenNames">
+ <xs:selector xpath="token"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ <!-- Each string must be unique, otherwise one string can map to two or
+ more enums. -->
+ <xs:unique name="tokenValues">
+ <xs:selector xpath="token"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="boilerplate" minOccurs="0" maxOccurs="1" type="boilerplateElementType"/>
+
+ </xs:sequence>
+ <xs:attribute name="className" type="cppIdentifierType"/>
+ <xs:attribute name="includeGuardName" type="cppIdentifierType"/>
+ <xs:attribute name="headerFile" type="filenameType" use="required"/>
+ <xs:attribute name="namespace" type="cppIdentifierType" use="optional"/>
+ <xs:attribute name="sourceFile" type="filenameType" use="required"/>
+ <xs:attribute name="scope" type="scopeType" use="required"/>
+ <xs:attribute name="defaultToken" type="cppIdentifierType" use="required"/>
+ <xs:attribute name="hasToString" type="xs:boolean" use="required"/>
+ <xs:attribute name="tokenEnum" type="cppIdentifierType" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="tokensElementType">
+ <xs:sequence>
+ <xs:element name="token" maxOccurs="unbounded" type="tokenElementType" minOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="tokenElementType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" use="optional" type="cppIdentifierType"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="boilerplateElementType">
+ <xs:sequence>
+ <xs:element name="prolog" maxOccurs="1" type="prologElementType" minOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="prologElementType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string"/>
+ </xs:simpleContent>
+ </xs:complexType>
+
+</xs:schema>
+<!--
+vim: et:ts=4:sw=4:sts=4
+-->
diff --git a/src/xmlpatterns/query.pri b/src/xmlpatterns/query.pri
new file mode 100644
index 0000000..fab1940
--- /dev/null
+++ b/src/xmlpatterns/query.pri
@@ -0,0 +1,14 @@
+include($$PWD/common.pri)
+include($$PWD/acceltree/acceltree.pri)
+include($$PWD/api/api.pri)
+include($$PWD/data/data.pri)
+include($$PWD/environment/environment.pri)
+include($$PWD/expr/expr.pri)
+include($$PWD/functions/functions.pri)
+include($$PWD/iterators/iterators.pri)
+include($$PWD/janitors/janitors.pri)
+include($$PWD/parser/parser.pri)
+include($$PWD/projection/projection.pri)
+include($$PWD/type/type.pri)
+include($$PWD/utils/utils.pri)
+include($$PWD/qobjectmodel/qobjectmodel.pri, "", true)
diff --git a/src/xmlpatterns/schema/.gitignore b/src/xmlpatterns/schema/.gitignore
new file mode 100644
index 0000000..2b29f27
--- /dev/null
+++ b/src/xmlpatterns/schema/.gitignore
@@ -0,0 +1 @@
+tests
diff --git a/src/xmlpatterns/schema/builtinschemas.qrc b/src/xmlpatterns/schema/builtinschemas.qrc
new file mode 100644
index 0000000..fb43d78
--- /dev/null
+++ b/src/xmlpatterns/schema/builtinschemas.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file alias="http://www.w3.org/XML/1998/namespace">schemas/xml.xsd</file>
+</qresource>
+</RCC>
diff --git a/src/xmlpatterns/schema/doc/All_diagram.dot b/src/xmlpatterns/schema/doc/All_diagram.dot
new file mode 100644
index 0000000..3352b72
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/All_diagram.dot
@@ -0,0 +1,13 @@
+digraph All {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Alternative_diagram.dot b/src/xmlpatterns/schema/doc/Alternative_diagram.dot
new file mode 100644
index 0000000..2119c49
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Alternative_diagram.dot
@@ -0,0 +1,11 @@
+digraph Alternative {
+ mindist = 2.0
+ 1 -> 3 [label="complexType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="complexType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Annotation_diagram.dot b/src/xmlpatterns/schema/doc/Annotation_diagram.dot
new file mode 100644
index 0000000..260b6f7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Annotation_diagram.dot
@@ -0,0 +1,9 @@
+digraph Annotation {
+ mindist = 2.0
+ 1 -> 2 [label="appinfo"]
+ 1 -> 2 [label="documentation"]
+ 2 -> 2 [label="appinfo"]
+ 2 -> 2 [label="documentation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot b/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot
new file mode 100644
index 0000000..d252ebd
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot
@@ -0,0 +1,6 @@
+digraph AnyAttribute {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Any_diagram.dot b/src/xmlpatterns/schema/doc/Any_diagram.dot
new file mode 100644
index 0000000..f54063f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Any_diagram.dot
@@ -0,0 +1,6 @@
+digraph Any {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Assert_diagram.dot b/src/xmlpatterns/schema/doc/Assert_diagram.dot
new file mode 100644
index 0000000..7093bef
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Assert_diagram.dot
@@ -0,0 +1,6 @@
+digraph Assert {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Choice_diagram.dot b/src/xmlpatterns/schema/doc/Choice_diagram.dot
new file mode 100644
index 0000000..7b32016
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Choice_diagram.dot
@@ -0,0 +1,22 @@
+digraph Choice {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot
new file mode 100644
index 0000000..6131612
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot
@@ -0,0 +1,47 @@
+digraph ComplexContentExtension {
+ mindist = 2.0
+ 1 -> 4 [label="choice"]
+ 1 -> 4 [label="group"]
+ 1 -> 4 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="sequence"]
+ 1 -> 6 [label="anyAttribute"]
+ 1 -> 7 [label="assert"]
+ 1 -> 3 [label="openContent"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 5 [label="attributeGroup"]
+ 2 -> 4 [label="choice"]
+ 2 -> 4 [label="group"]
+ 2 -> 4 [label="all"]
+ 2 -> 4 [label="sequence"]
+ 2 -> 6 [label="anyAttribute"]
+ 2 -> 7 [label="assert"]
+ 2 -> 3 [label="openContent"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 5 [label="attributeGroup"]
+ 3 -> 4 [label="choice"]
+ 3 -> 4 [label="group"]
+ 3 -> 4 [label="all"]
+ 3 -> 4 [label="sequence"]
+ 3 -> 6 [label="anyAttribute"]
+ 3 -> 7 [label="assert"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 5 [label="attributeGroup"]
+ 4 -> 6 [label="anyAttribute"]
+ 4 -> 7 [label="assert"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 5 [label="attributeGroup"]
+ 5 -> 6 [label="anyAttribute"]
+ 5 -> 7 [label="assert"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 7 [label="assert"]
+ 7 -> 7 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot
new file mode 100644
index 0000000..bfda892
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot
@@ -0,0 +1,47 @@
+digraph ComplexContentRestriction {
+ mindist = 2.0
+ 1 -> 4 [label="choice"]
+ 1 -> 4 [label="group"]
+ 1 -> 4 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="sequence"]
+ 1 -> 6 [label="anyAttribute"]
+ 1 -> 7 [label="assert"]
+ 1 -> 3 [label="openContent"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 5 [label="attributeGroup"]
+ 2 -> 4 [label="choice"]
+ 2 -> 4 [label="group"]
+ 2 -> 4 [label="all"]
+ 2 -> 4 [label="sequence"]
+ 2 -> 6 [label="anyAttribute"]
+ 2 -> 7 [label="assert"]
+ 2 -> 3 [label="openContent"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 5 [label="attributeGroup"]
+ 3 -> 4 [label="choice"]
+ 3 -> 4 [label="group"]
+ 3 -> 4 [label="all"]
+ 3 -> 4 [label="sequence"]
+ 3 -> 6 [label="anyAttribute"]
+ 3 -> 7 [label="assert"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 5 [label="attributeGroup"]
+ 4 -> 6 [label="anyAttribute"]
+ 4 -> 7 [label="assert"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 5 [label="attributeGroup"]
+ 5 -> 6 [label="anyAttribute"]
+ 5 -> 7 [label="assert"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 7 [label="assert"]
+ 7 -> 7 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot
new file mode 100644
index 0000000..949c27e
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot
@@ -0,0 +1,11 @@
+digraph ComplexContent {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="extension"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="extension"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot b/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot
new file mode 100644
index 0000000..61e7d14
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot
@@ -0,0 +1,9 @@
+digraph DefaultOpenContent {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="any"]
+ 2 -> 3 [label="any"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot b/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot
new file mode 100644
index 0000000..91be76b
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph EnumerationFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Field_diagram.dot b/src/xmlpatterns/schema/doc/Field_diagram.dot
new file mode 100644
index 0000000..1c597b3
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Field_diagram.dot
@@ -0,0 +1,6 @@
+digraph Field {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot b/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot
new file mode 100644
index 0000000..5e098b3
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph FractionDigitsFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot b/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot
new file mode 100644
index 0000000..25a1a43
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot
@@ -0,0 +1,9 @@
+digraph GlobalAttribute {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot b/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot
new file mode 100644
index 0000000..05e40b7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot
@@ -0,0 +1,52 @@
+digraph GlobalComplexType {
+ mindist = 2.0
+ 1 -> 5 [label="choice"]
+ 1 -> 3 [label="complexContent"]
+ 1 -> 5 [label="group"]
+ 1 -> 5 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="sequence"]
+ 1 -> 3 [label="simpleContent"]
+ 1 -> 7 [label="anyAttribute"]
+ 1 -> 8 [label="assert"]
+ 1 -> 4 [label="openContent"]
+ 1 -> 6 [label="attribute"]
+ 1 -> 6 [label="attributeGroup"]
+ 2 -> 5 [label="choice"]
+ 2 -> 3 [label="complexContent"]
+ 2 -> 5 [label="group"]
+ 2 -> 5 [label="all"]
+ 2 -> 5 [label="sequence"]
+ 2 -> 3 [label="simpleContent"]
+ 2 -> 7 [label="anyAttribute"]
+ 2 -> 8 [label="assert"]
+ 2 -> 4 [label="openContent"]
+ 2 -> 6 [label="attribute"]
+ 2 -> 6 [label="attributeGroup"]
+ 4 -> 5 [label="choice"]
+ 4 -> 5 [label="group"]
+ 4 -> 5 [label="all"]
+ 4 -> 5 [label="sequence"]
+ 4 -> 7 [label="anyAttribute"]
+ 4 -> 8 [label="assert"]
+ 4 -> 6 [label="attribute"]
+ 4 -> 6 [label="attributeGroup"]
+ 5 -> 7 [label="anyAttribute"]
+ 5 -> 8 [label="assert"]
+ 5 -> 6 [label="attribute"]
+ 5 -> 6 [label="attributeGroup"]
+ 6 -> 7 [label="anyAttribute"]
+ 6 -> 8 [label="assert"]
+ 6 -> 6 [label="attribute"]
+ 6 -> 6 [label="attributeGroup"]
+ 7 -> 8 [label="assert"]
+ 8 -> 8 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+ 8 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot b/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot
new file mode 100644
index 0000000..20447a7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot
@@ -0,0 +1,32 @@
+digraph GlobalElement {
+ mindist = 2.0
+ 1 -> 3 [label="complexType"]
+ 1 -> 4 [label="alternative"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="key"]
+ 1 -> 3 [label="simpleType"]
+ 1 -> 5 [label="keyref"]
+ 1 -> 5 [label="unique"]
+ 2 -> 3 [label="complexType"]
+ 2 -> 4 [label="alternative"]
+ 2 -> 5 [label="key"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 5 [label="keyref"]
+ 2 -> 5 [label="unique"]
+ 3 -> 4 [label="alternative"]
+ 3 -> 5 [label="key"]
+ 3 -> 5 [label="keyref"]
+ 3 -> 5 [label="unique"]
+ 4 -> 4 [label="alternative"]
+ 4 -> 5 [label="key"]
+ 4 -> 5 [label="keyref"]
+ 4 -> 5 [label="unique"]
+ 5 -> 5 [label="key"]
+ 5 -> 5 [label="keyref"]
+ 5 -> 5 [label="unique"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot b/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot
new file mode 100644
index 0000000..ccb7f54
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot
@@ -0,0 +1,13 @@
+digraph GlobalSimpleType {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="list"]
+ 1 -> 3 [label="union"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="list"]
+ 2 -> 3 [label="union"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Import_diagram.dot b/src/xmlpatterns/schema/doc/Import_diagram.dot
new file mode 100644
index 0000000..3484bc3
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Import_diagram.dot
@@ -0,0 +1,6 @@
+digraph Import {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Include_diagram.dot b/src/xmlpatterns/schema/doc/Include_diagram.dot
new file mode 100644
index 0000000..357e4c9
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Include_diagram.dot
@@ -0,0 +1,6 @@
+digraph Include {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/KeyRef_diagram.dot b/src/xmlpatterns/schema/doc/KeyRef_diagram.dot
new file mode 100644
index 0000000..ff425b9
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/KeyRef_diagram.dot
@@ -0,0 +1,12 @@
+digraph KeyRef {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="selector"]
+ 2 -> 3 [label="selector"]
+ 3 -> 4 [label="field"]
+ 4 -> 4 [label="field"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=circle, style=filled, color=red]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Key_diagram.dot b/src/xmlpatterns/schema/doc/Key_diagram.dot
new file mode 100644
index 0000000..bbc09cd
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Key_diagram.dot
@@ -0,0 +1,12 @@
+digraph Key {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="selector"]
+ 2 -> 3 [label="selector"]
+ 3 -> 4 [label="field"]
+ 4 -> 4 [label="field"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=circle, style=filled, color=red]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot
new file mode 100644
index 0000000..1f9205b
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph LengthFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/List_diagram.dot b/src/xmlpatterns/schema/doc/List_diagram.dot
new file mode 100644
index 0000000..44cc698
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/List_diagram.dot
@@ -0,0 +1,9 @@
+digraph List {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalAll_diagram.dot b/src/xmlpatterns/schema/doc/LocalAll_diagram.dot
new file mode 100644
index 0000000..88f1b61
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalAll_diagram.dot
@@ -0,0 +1,13 @@
+digraph LocalAll {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot b/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot
new file mode 100644
index 0000000..b01f0cf
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot
@@ -0,0 +1,9 @@
+digraph LocalAttribute {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot b/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot
new file mode 100644
index 0000000..b16c47f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot
@@ -0,0 +1,22 @@
+digraph LocalChoice {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot b/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot
new file mode 100644
index 0000000..92c54b7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot
@@ -0,0 +1,52 @@
+digraph LocalComplexType {
+ mindist = 2.0
+ 1 -> 5 [label="choice"]
+ 1 -> 3 [label="complexContent"]
+ 1 -> 5 [label="group"]
+ 1 -> 5 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="sequence"]
+ 1 -> 3 [label="simpleContent"]
+ 1 -> 7 [label="anyAttribute"]
+ 1 -> 8 [label="assert"]
+ 1 -> 4 [label="openContent"]
+ 1 -> 6 [label="attribute"]
+ 1 -> 6 [label="attributeGroup"]
+ 2 -> 5 [label="choice"]
+ 2 -> 3 [label="complexContent"]
+ 2 -> 5 [label="group"]
+ 2 -> 5 [label="all"]
+ 2 -> 5 [label="sequence"]
+ 2 -> 3 [label="simpleContent"]
+ 2 -> 7 [label="anyAttribute"]
+ 2 -> 8 [label="assert"]
+ 2 -> 4 [label="openContent"]
+ 2 -> 6 [label="attribute"]
+ 2 -> 6 [label="attributeGroup"]
+ 4 -> 5 [label="choice"]
+ 4 -> 5 [label="group"]
+ 4 -> 5 [label="all"]
+ 4 -> 5 [label="sequence"]
+ 4 -> 7 [label="anyAttribute"]
+ 4 -> 8 [label="assert"]
+ 4 -> 6 [label="attribute"]
+ 4 -> 6 [label="attributeGroup"]
+ 5 -> 7 [label="anyAttribute"]
+ 5 -> 8 [label="assert"]
+ 5 -> 6 [label="attribute"]
+ 5 -> 6 [label="attributeGroup"]
+ 6 -> 7 [label="anyAttribute"]
+ 6 -> 8 [label="assert"]
+ 6 -> 6 [label="attribute"]
+ 6 -> 6 [label="attributeGroup"]
+ 7 -> 8 [label="assert"]
+ 8 -> 8 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+ 8 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalElement_diagram.dot b/src/xmlpatterns/schema/doc/LocalElement_diagram.dot
new file mode 100644
index 0000000..397397a
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalElement_diagram.dot
@@ -0,0 +1,32 @@
+digraph LocalElement {
+ mindist = 2.0
+ 1 -> 3 [label="complexType"]
+ 1 -> 4 [label="alternative"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="key"]
+ 1 -> 3 [label="simpleType"]
+ 1 -> 5 [label="keyref"]
+ 1 -> 5 [label="unique"]
+ 2 -> 3 [label="complexType"]
+ 2 -> 4 [label="alternative"]
+ 2 -> 5 [label="key"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 5 [label="keyref"]
+ 2 -> 5 [label="unique"]
+ 3 -> 4 [label="alternative"]
+ 3 -> 5 [label="key"]
+ 3 -> 5 [label="keyref"]
+ 3 -> 5 [label="unique"]
+ 4 -> 4 [label="alternative"]
+ 4 -> 5 [label="key"]
+ 4 -> 5 [label="keyref"]
+ 4 -> 5 [label="unique"]
+ 5 -> 5 [label="key"]
+ 5 -> 5 [label="keyref"]
+ 5 -> 5 [label="unique"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot b/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot
new file mode 100644
index 0000000..0dc7f39
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot
@@ -0,0 +1,22 @@
+digraph LocalSequence {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot b/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot
new file mode 100644
index 0000000..ac13305
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot
@@ -0,0 +1,13 @@
+digraph LocalSimpleType {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="list"]
+ 1 -> 3 [label="union"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="list"]
+ 2 -> 3 [label="union"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot
new file mode 100644
index 0000000..28364f7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MaxExclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot
new file mode 100644
index 0000000..9e2c265
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MaxInclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot
new file mode 100644
index 0000000..d565217
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MaxLengthFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot
new file mode 100644
index 0000000..d3b3f1f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MinExclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot
new file mode 100644
index 0000000..e5ca65d
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MinInclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot
new file mode 100644
index 0000000..1dcced4
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MinLengthFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot b/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot
new file mode 100644
index 0000000..1754f67
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot
@@ -0,0 +1,17 @@
+digraph NamedAttributeGroup {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="anyAttribute"]
+ 1 -> 3 [label="attribute"]
+ 1 -> 3 [label="attributeGroup"]
+ 2 -> 4 [label="anyAttribute"]
+ 2 -> 3 [label="attribute"]
+ 2 -> 3 [label="attributeGroup"]
+ 3 -> 4 [label="anyAttribute"]
+ 3 -> 3 [label="attribute"]
+ 3 -> 3 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot b/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot
new file mode 100644
index 0000000..6d9a289
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot
@@ -0,0 +1,13 @@
+digraph NamedGroup {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="all"]
+ 2 -> 3 [label="sequence"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Notation_diagram.dot b/src/xmlpatterns/schema/doc/Notation_diagram.dot
new file mode 100644
index 0000000..951f26a
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Notation_diagram.dot
@@ -0,0 +1,6 @@
+digraph Notation {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Override_diagram.dot b/src/xmlpatterns/schema/doc/Override_diagram.dot
new file mode 100644
index 0000000..448451a
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Override_diagram.dot
@@ -0,0 +1,21 @@
+digraph Override {
+ mindist = 2.0
+ 1 -> 2 [label="group"]
+ 1 -> 2 [label="complexType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 2 [label="simpleType"]
+ 1 -> 2 [label="element"]
+ 1 -> 2 [label="notation"]
+ 1 -> 2 [label="attribute"]
+ 1 -> 2 [label="attributeGroup"]
+ 2 -> 2 [label="group"]
+ 2 -> 2 [label="complexType"]
+ 2 -> 2 [label="annotation"]
+ 2 -> 2 [label="simpleType"]
+ 2 -> 2 [label="element"]
+ 2 -> 2 [label="notation"]
+ 2 -> 2 [label="attribute"]
+ 2 -> 2 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot b/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot
new file mode 100644
index 0000000..794d74c
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph PatternFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Redefine_diagram.dot b/src/xmlpatterns/schema/doc/Redefine_diagram.dot
new file mode 100644
index 0000000..ba4871d
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Redefine_diagram.dot
@@ -0,0 +1,15 @@
+digraph Redefine {
+ mindist = 2.0
+ 1 -> 2 [label="group"]
+ 1 -> 2 [label="complexType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 2 [label="simpleType"]
+ 1 -> 2 [label="attributeGroup"]
+ 2 -> 2 [label="group"]
+ 2 -> 2 [label="complexType"]
+ 2 -> 2 [label="annotation"]
+ 2 -> 2 [label="simpleType"]
+ 2 -> 2 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot b/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot
new file mode 100644
index 0000000..fd08872
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot
@@ -0,0 +1,6 @@
+digraph ReferredAttributeGroup {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot b/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot
new file mode 100644
index 0000000..c32f69f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot
@@ -0,0 +1,13 @@
+digraph ReferredGroup {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="all"]
+ 2 -> 3 [label="sequence"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Schema_diagram.dot b/src/xmlpatterns/schema/doc/Schema_diagram.dot
new file mode 100644
index 0000000..7d39337
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Schema_diagram.dot
@@ -0,0 +1,66 @@
+digraph Schema {
+ mindist = 2.0
+ 1 -> 5 [label="group"]
+ 1 -> 5 [label="complexType"]
+ 1 -> 2 [label="import"]
+ 1 -> 2 [label="include"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="defaultOpenContent"]
+ 1 -> 5 [label="simpleType"]
+ 1 -> 5 [label="element"]
+ 1 -> 5 [label="notation"]
+ 1 -> 2 [label="override"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 5 [label="attributeGroup"]
+ 1 -> 2 [label="redefine"]
+ 2 -> 5 [label="group"]
+ 2 -> 5 [label="complexType"]
+ 2 -> 2 [label="import"]
+ 2 -> 2 [label="include"]
+ 2 -> 2 [label="annotation"]
+ 2 -> 3 [label="defaultOpenContent"]
+ 2 -> 5 [label="simpleType"]
+ 2 -> 5 [label="element"]
+ 2 -> 5 [label="notation"]
+ 2 -> 2 [label="override"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 5 [label="attributeGroup"]
+ 2 -> 2 [label="redefine"]
+ 3 -> 5 [label="group"]
+ 3 -> 5 [label="complexType"]
+ 3 -> 4 [label="annotation"]
+ 3 -> 5 [label="simpleType"]
+ 3 -> 5 [label="element"]
+ 3 -> 5 [label="notation"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 5 [label="attributeGroup"]
+ 4 -> 5 [label="group"]
+ 4 -> 5 [label="complexType"]
+ 4 -> 5 [label="simpleType"]
+ 4 -> 5 [label="element"]
+ 4 -> 5 [label="notation"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 5 [label="attributeGroup"]
+ 5 -> 5 [label="group"]
+ 5 -> 5 [label="complexType"]
+ 5 -> 6 [label="annotation"]
+ 5 -> 5 [label="simpleType"]
+ 5 -> 5 [label="element"]
+ 5 -> 5 [label="notation"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 5 [label="group"]
+ 6 -> 5 [label="complexType"]
+ 6 -> 6 [label="annotation"]
+ 6 -> 5 [label="simpleType"]
+ 6 -> 5 [label="element"]
+ 6 -> 5 [label="notation"]
+ 6 -> 5 [label="attribute"]
+ 6 -> 5 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Selector_diagram.dot b/src/xmlpatterns/schema/doc/Selector_diagram.dot
new file mode 100644
index 0000000..f3e93dc
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Selector_diagram.dot
@@ -0,0 +1,6 @@
+digraph Selector {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Sequence_diagram.dot b/src/xmlpatterns/schema/doc/Sequence_diagram.dot
new file mode 100644
index 0000000..9172744
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Sequence_diagram.dot
@@ -0,0 +1,22 @@
+digraph Sequence {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot
new file mode 100644
index 0000000..3ceebfd
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot
@@ -0,0 +1,23 @@
+digraph SimpleContentExtension {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="anyAttribute"]
+ 1 -> 5 [label="assert"]
+ 1 -> 3 [label="attribute"]
+ 1 -> 3 [label="attributeGroup"]
+ 2 -> 4 [label="anyAttribute"]
+ 2 -> 5 [label="assert"]
+ 2 -> 3 [label="attribute"]
+ 2 -> 3 [label="attributeGroup"]
+ 3 -> 4 [label="anyAttribute"]
+ 3 -> 5 [label="assert"]
+ 3 -> 3 [label="attribute"]
+ 3 -> 3 [label="attributeGroup"]
+ 4 -> 5 [label="assert"]
+ 5 -> 5 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot
new file mode 100644
index 0000000..75b0b71
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot
@@ -0,0 +1,87 @@
+digraph SimpleContentRestriction {
+ mindist = 2.0
+ 1 -> 3 [label="simpleType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="length"]
+ 1 -> 6 [label="anyAttribute"]
+ 1 -> 4 [label="maxExclusive"]
+ 1 -> 4 [label="totalDigits"]
+ 1 -> 4 [label="maxInclusive"]
+ 1 -> 4 [label="maxLength"]
+ 1 -> 7 [label="assert"]
+ 1 -> 4 [label="assertion"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 4 [label="minExclusive"]
+ 1 -> 5 [label="attributeGroup"]
+ 1 -> 4 [label="minInclusive"]
+ 1 -> 4 [label="minLength"]
+ 1 -> 4 [label="whiteSpace"]
+ 1 -> 4 [label="pattern"]
+ 1 -> 4 [label="enumeration"]
+ 1 -> 4 [label="fractionDigits"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 4 [label="length"]
+ 2 -> 6 [label="anyAttribute"]
+ 2 -> 4 [label="maxExclusive"]
+ 2 -> 4 [label="totalDigits"]
+ 2 -> 4 [label="maxInclusive"]
+ 2 -> 4 [label="maxLength"]
+ 2 -> 7 [label="assert"]
+ 2 -> 4 [label="assertion"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 4 [label="minExclusive"]
+ 2 -> 5 [label="attributeGroup"]
+ 2 -> 4 [label="minInclusive"]
+ 2 -> 4 [label="minLength"]
+ 2 -> 4 [label="whiteSpace"]
+ 2 -> 4 [label="pattern"]
+ 2 -> 4 [label="enumeration"]
+ 2 -> 4 [label="fractionDigits"]
+ 3 -> 4 [label="fractionDigits"]
+ 3 -> 4 [label="minLength"]
+ 3 -> 4 [label="whiteSpace"]
+ 3 -> 6 [label="anyAttribute"]
+ 3 -> 4 [label="length"]
+ 3 -> 7 [label="assert"]
+ 3 -> 4 [label="maxExclusive"]
+ 3 -> 4 [label="enumeration"]
+ 3 -> 4 [label="assertion"]
+ 3 -> 4 [label="maxInclusive"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 4 [label="maxLength"]
+ 3 -> 4 [label="pattern"]
+ 3 -> 4 [label="totalDigits"]
+ 3 -> 5 [label="attributeGroup"]
+ 3 -> 4 [label="minExclusive"]
+ 3 -> 4 [label="minInclusive"]
+ 4 -> 4 [label="fractionDigits"]
+ 4 -> 4 [label="minLength"]
+ 4 -> 4 [label="whiteSpace"]
+ 4 -> 6 [label="anyAttribute"]
+ 4 -> 4 [label="length"]
+ 4 -> 7 [label="assert"]
+ 4 -> 4 [label="maxExclusive"]
+ 4 -> 4 [label="enumeration"]
+ 4 -> 4 [label="assertion"]
+ 4 -> 4 [label="maxInclusive"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 4 [label="maxLength"]
+ 4 -> 4 [label="pattern"]
+ 4 -> 4 [label="totalDigits"]
+ 4 -> 5 [label="attributeGroup"]
+ 4 -> 4 [label="minExclusive"]
+ 4 -> 4 [label="minInclusive"]
+ 5 -> 6 [label="anyAttribute"]
+ 5 -> 7 [label="assert"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 7 [label="assert"]
+ 7 -> 7 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot
new file mode 100644
index 0000000..c996329
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot
@@ -0,0 +1,11 @@
+digraph SimpleContent {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="extension"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="extension"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot b/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot
new file mode 100644
index 0000000..09cb041
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot
@@ -0,0 +1,62 @@
+digraph SimpleRestriction {
+ mindist = 2.0
+ 1 -> 4 [label="fractionDigits"]
+ 1 -> 4 [label="minLength"]
+ 1 -> 4 [label="whiteSpace"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 1 -> 4 [label="length"]
+ 1 -> 4 [label="maxExclusive"]
+ 1 -> 4 [label="enumeration"]
+ 1 -> 4 [label="assertion"]
+ 1 -> 4 [label="maxInclusive"]
+ 1 -> 4 [label="maxLength"]
+ 1 -> 4 [label="pattern"]
+ 1 -> 4 [label="totalDigits"]
+ 1 -> 4 [label="minExclusive"]
+ 1 -> 4 [label="minInclusive"]
+ 2 -> 4 [label="fractionDigits"]
+ 2 -> 4 [label="minLength"]
+ 2 -> 4 [label="whiteSpace"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 4 [label="length"]
+ 2 -> 4 [label="maxExclusive"]
+ 2 -> 4 [label="enumeration"]
+ 2 -> 4 [label="assertion"]
+ 2 -> 4 [label="maxInclusive"]
+ 2 -> 4 [label="maxLength"]
+ 2 -> 4 [label="pattern"]
+ 2 -> 4 [label="totalDigits"]
+ 2 -> 4 [label="minExclusive"]
+ 2 -> 4 [label="minInclusive"]
+ 3 -> 4 [label="fractionDigits"]
+ 3 -> 4 [label="minLength"]
+ 3 -> 4 [label="whiteSpace"]
+ 3 -> 4 [label="length"]
+ 3 -> 4 [label="maxExclusive"]
+ 3 -> 4 [label="enumeration"]
+ 3 -> 4 [label="assertion"]
+ 3 -> 4 [label="maxInclusive"]
+ 3 -> 4 [label="maxLength"]
+ 3 -> 4 [label="pattern"]
+ 3 -> 4 [label="totalDigits"]
+ 3 -> 4 [label="minExclusive"]
+ 3 -> 4 [label="minInclusive"]
+ 4 -> 4 [label="fractionDigits"]
+ 4 -> 4 [label="minLength"]
+ 4 -> 4 [label="whiteSpace"]
+ 4 -> 4 [label="length"]
+ 4 -> 4 [label="maxExclusive"]
+ 4 -> 4 [label="enumeration"]
+ 4 -> 4 [label="assertion"]
+ 4 -> 4 [label="maxInclusive"]
+ 4 -> 4 [label="maxLength"]
+ 4 -> 4 [label="pattern"]
+ 4 -> 4 [label="totalDigits"]
+ 4 -> 4 [label="minExclusive"]
+ 4 -> 4 [label="minInclusive"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot b/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot
new file mode 100644
index 0000000..0ef4cd6
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph TotalDigitsFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Union_diagram.dot b/src/xmlpatterns/schema/doc/Union_diagram.dot
new file mode 100644
index 0000000..d6c1865
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Union_diagram.dot
@@ -0,0 +1,10 @@
+digraph Union {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 3 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Unique_diagram.dot b/src/xmlpatterns/schema/doc/Unique_diagram.dot
new file mode 100644
index 0000000..5b1d098
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Unique_diagram.dot
@@ -0,0 +1,12 @@
+digraph Unique {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="selector"]
+ 2 -> 3 [label="selector"]
+ 3 -> 4 [label="field"]
+ 4 -> 4 [label="field"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=circle, style=filled, color=red]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot b/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot
new file mode 100644
index 0000000..596403c
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph WhiteSpaceFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/legend.dot b/src/xmlpatterns/schema/doc/legend.dot
new file mode 100644
index 0000000..4f5792e
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/legend.dot
@@ -0,0 +1,7 @@
+digraph {
+ size="5,4"
+ 1 [label=" start state ", shape=circle, style=filled, color=blue]
+ 2 [label="start/end state", shape=doublecircle, style=filled, color=blue]
+ 3 [label=" internal state", shape=circle, style=filled, color=red]
+ 4 [label=" end state ", shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp
new file mode 100644
index 0000000..05b87e3
--- /dev/null
+++ b/src/xmlpatterns/schema/qnamespacesupport.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
+#include "qnamespacesupport_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamespaceSupport::NamespaceSupport()
+{
+}
+
+NamespaceSupport::NamespaceSupport(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+ // the XML namespace
+ m_ns.insert(StandardPrefixes::xml, StandardNamespaces::xml);
+}
+
+void NamespaceSupport::setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode)
+{
+ m_ns.insert(prefixCode, namespaceCode);
+}
+
+void NamespaceSupport::setPrefixes(const QXmlStreamNamespaceDeclarations &declarations)
+{
+ for (int i = 0; i < declarations.count(); i++) {
+ const QXmlStreamNamespaceDeclaration declaration = declarations.at(i);
+
+ const QXmlName::PrefixCode prefixCode = m_namePool->allocatePrefix(declaration.prefix().toString());
+ const QXmlName::NamespaceCode namespaceCode = m_namePool->allocateNamespace(declaration.namespaceUri().toString());
+ m_ns.insert(prefixCode, namespaceCode);
+ }
+}
+
+void NamespaceSupport::setTargetNamespace(const QXmlName::NamespaceCode namespaceCode)
+{
+ m_ns.insert(0, namespaceCode);
+}
+
+QXmlName::PrefixCode NamespaceSupport::prefix(const QXmlName::NamespaceCode namespaceCode) const
+{
+ NamespaceHash::const_iterator itc, it = m_ns.constBegin();
+ while ((itc=it) != m_ns.constEnd()) {
+ ++it;
+ if (*itc == namespaceCode)
+ return itc.key();
+ }
+ return 0;
+}
+
+QXmlName::NamespaceCode NamespaceSupport::uri(const QXmlName::PrefixCode prefixCode) const
+{
+ return m_ns.value(prefixCode);
+}
+
+bool NamespaceSupport::processName(const QString& qname, NameType type, QXmlName &name) const
+{
+ int len = qname.size();
+ const QChar *data = qname.constData();
+ for (int pos = 0; pos < len; ++pos) {
+ if (data[pos] == QLatin1Char(':')) {
+ const QXmlName::PrefixCode prefixCode = m_namePool->allocatePrefix(qname.left(pos));
+ if (!m_ns.contains(prefixCode))
+ return false;
+ const QXmlName::NamespaceCode namespaceCode = uri(prefixCode);
+ const QXmlName::LocalNameCode localNameCode = m_namePool->allocateLocalName(qname.mid(pos + 1));
+ name = QXmlName(namespaceCode, localNameCode, prefixCode);
+ return true;
+ }
+ }
+
+ // there was no ':'
+ QXmlName::NamespaceCode namespaceCode = 0;
+ // attributes don't take default namespace
+ if (type == ElementName && !m_ns.isEmpty()) {
+ namespaceCode = m_ns.value(0); // get default namespace
+ }
+
+ const QXmlName::LocalNameCode localNameCode = m_namePool->allocateLocalName(qname);
+ name = QXmlName(namespaceCode, localNameCode, 0);
+
+ return true;
+}
+
+void NamespaceSupport::pushContext()
+{
+ m_nsStack.push(m_ns);
+}
+
+void NamespaceSupport::popContext()
+{
+ m_ns.clear();
+ if(!m_nsStack.isEmpty())
+ m_ns = m_nsStack.pop();
+}
+
+QList<QXmlName> NamespaceSupport::namespaceBindings() const
+{
+ QList<QXmlName> bindings;
+
+ QHashIterator<QXmlName::PrefixCode, QXmlName::NamespaceCode> it(m_ns);
+ while (it.hasNext()) {
+ it.next();
+ bindings.append(QXmlName(it.value(), StandardLocalNames::empty, it.key()));
+ }
+
+ return bindings;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qnamespacesupport_p.h b/src/xmlpatterns/schema/qnamespacesupport_p.h
new file mode 100644
index 0000000..2a2cb1e
--- /dev/null
+++ b/src/xmlpatterns/schema/qnamespacesupport_p.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamespaceSupport_H
+#define Patternist_NamespaceSupport_H
+
+#include "qnamepool_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QStack>
+#include <QtCore/QXmlStreamNamespaceDeclarations>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class for handling nested namespace declarations.
+ *
+ * This class is mostly an adaption of QXmlNamespaceSupport to the NamePool
+ * mechanism used in XmlPatterns.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class NamespaceSupport
+ {
+ public:
+ /**
+ * Describes whether the name to process is an attribute or element.
+ */
+ enum NameType
+ {
+ AttributeName, ///< An attribute name to process.
+ ElementName ///< An element name to process.
+ };
+
+ /**
+ * Creates an empty namespace support object.
+ */
+ NamespaceSupport();
+
+ /**
+ * Creates a new namespace support object.
+ *
+ * @param namePool The name pool where all processed names are stored in.
+ */
+ NamespaceSupport(const NamePool::Ptr &namePool);
+
+ /**
+ * Adds a new prefix-to-namespace binding.
+ *
+ * @param prefixCode The name pool code for the prefix.
+ * @param namespaceCode The name pool code for the namespace.
+ */
+ void setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode);
+
+ /**
+ * Adds the prefix-to-namespace bindings from @p declarations to
+ * the namespace support.
+ */
+ void setPrefixes(const QXmlStreamNamespaceDeclarations &declarations);
+
+ /**
+ * Sets the name pool code of the target namespace of the schema the
+ * namespace support works on.
+ */
+ void setTargetNamespace(const QXmlName::NamespaceCode code);
+
+ /**
+ * Returns the prefix code for the given namespace @p code.
+ */
+ QXmlName::PrefixCode prefix(const QXmlName::NamespaceCode code) const;
+
+ /**
+ * Returns the namespace code for the given prefix @p code.
+ */
+ QXmlName::NamespaceCode uri(const QXmlName::PrefixCode code) const;
+
+ /**
+ * Converts the given @p qualifiedName to a resolved QXmlName @p name according
+ * to the current namespace mapping.
+ *
+ * @param qualifiedName The full qualified name.
+ * @param type The type of name processing.
+ * @param name The resolved QXmlName.
+ *
+ * @returns @c true if the name could be processed correctly or @c false if the
+ * namespace prefix is unknown.
+ */
+ bool processName(const QString &qualifiedName, NameType type, QXmlName &name) const;
+
+ /**
+ * Pushes the current namespace mapping onto the stack.
+ */
+ void pushContext();
+
+ /**
+ * Pops the current namespace mapping from the stack.
+ */
+ void popContext();
+
+ /**
+ * Returns the list of namespace bindings.
+ */
+ QList<QXmlName> namespaceBindings() const;
+
+ private:
+ typedef QHash<QXmlName::PrefixCode, QXmlName::NamespaceCode> NamespaceHash;
+
+ NamePool::Ptr m_namePool;
+ QStack<NamespaceHash> m_nsStack;
+ NamespaceHash m_ns;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdalternative.cpp b/src/xmlpatterns/schema/qxsdalternative.cpp
new file mode 100644
index 0000000..279a184
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdalternative.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdalternative_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAlternative::setTest(const XsdXPathExpression::Ptr &test)
+{
+ m_test = test;
+}
+
+XsdXPathExpression::Ptr XsdAlternative::test() const
+{
+ return m_test;
+}
+
+void XsdAlternative::setType(const SchemaType::Ptr &type)
+{
+ m_type = type;
+}
+
+SchemaType::Ptr XsdAlternative::type() const
+{
+ return m_type;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdalternative_p.h b/src/xmlpatterns/schema/qxsdalternative_p.h
new file mode 100644
index 0000000..f94f0ac
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdalternative_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAlternative_H
+#define Patternist_XsdAlternative_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qschematype_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdxpathexpression_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD alternative object.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAlternative : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAlternative> Ptr;
+ typedef QList<XsdAlternative::Ptr> List;
+
+ /**
+ * Sets the xpath @p test of the alternative.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#tac-test">Test Definition</a>
+ */
+ void setTest(const XsdXPathExpression::Ptr &test);
+
+ /**
+ * Returns the xpath test of the alternative.
+ */
+ XsdXPathExpression::Ptr test() const;
+
+ /**
+ * Sets the @p type of the alternative.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#tac-type_definition">Type Definition</a>
+ */
+ void setType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the type of the alternative.
+ */
+ SchemaType::Ptr type() const;
+
+ private:
+ XsdXPathExpression::Ptr m_test;
+ SchemaType::Ptr m_type;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdannotated.cpp b/src/xmlpatterns/schema/qxsdannotated.cpp
new file mode 100644
index 0000000..151057d
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotated.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdannotated_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAnnotated::addAnnotation(const XsdAnnotation::Ptr &annotation)
+{
+ m_annotations.append(annotation);
+}
+
+void XsdAnnotated::addAnnotations(const XsdAnnotation::List &annotations)
+{
+ m_annotations << annotations;
+}
+
+XsdAnnotation::List XsdAnnotated::annotations() const
+{
+ return m_annotations;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdannotated_p.h b/src/xmlpatterns/schema/qxsdannotated_p.h
new file mode 100644
index 0000000..f8d7fe1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotated_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAnnotated_H
+#define Patternist_XsdAnnotated_H
+
+#include "qxsdannotation_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all XSD components with annotation content.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAnnotated
+ {
+ public:
+ /**
+ * Adds a new @p annotation to the component.
+ */
+ void addAnnotation(const XsdAnnotation::Ptr &annotation);
+
+ /**
+ * Adds a list of new @p annotations to the component.
+ */
+ void addAnnotations(const XsdAnnotation::List &annotations);
+
+ /**
+ * Returns the list of all annotations of the component.
+ */
+ XsdAnnotation::List annotations() const;
+
+ private:
+ XsdAnnotation::List m_annotations;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdannotation.cpp b/src/xmlpatterns/schema/qxsdannotation.cpp
new file mode 100644
index 0000000..9c76378
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotation.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdannotation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAnnotation::setId(const DerivedString<TypeID>::Ptr &id)
+{
+ m_id = id;
+}
+
+DerivedString<TypeID>::Ptr XsdAnnotation::id() const
+{
+ return m_id;
+}
+
+void XsdAnnotation::addApplicationInformation(const XsdApplicationInformation::Ptr &information)
+{
+ m_applicationInformation.append(information);
+}
+
+XsdApplicationInformation::List XsdAnnotation::applicationInformation() const
+{
+ return m_applicationInformation;
+}
+
+void XsdAnnotation::addDocumentation(const XsdDocumentation::Ptr &documentation)
+{
+ m_documentations.append(documentation);
+}
+
+XsdDocumentation::List XsdAnnotation::documentation() const
+{
+ return m_documentations;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdannotation_p.h b/src/xmlpatterns/schema/qxsdannotation_p.h
new file mode 100644
index 0000000..a8e2d55
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotation_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAnnotation_H
+#define Patternist_XsdAnnotation_H
+
+#include "qderivedstring_p.h"
+#include "qxsdapplicationinformation_p.h"
+#include "qxsddocumentation_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD annotation object.
+ *
+ * This class represents the <em>annotation</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAnnotations">here</a>.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAnnotation : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAnnotation> Ptr;
+ typedef QList<XsdAnnotation::Ptr> List;
+
+ /**
+ * Sets the @p id of the annotation.
+ */
+ void setId(const DerivedString<TypeID>::Ptr &id);
+
+ /**
+ * Returns the @p id of the annotation.
+ */
+ DerivedString<TypeID>::Ptr id() const;
+
+ /**
+ * Adds an application @p information to the annotation.
+ *
+ * The application information is meant to be interpreted by
+ * a software system, e.g. other parts of the XML processor pipeline.
+ */
+ void addApplicationInformation(const XsdApplicationInformation::Ptr &information);
+
+ /**
+ * Returns the list of all application information of the annotation.
+ */
+ XsdApplicationInformation::List applicationInformation() const;
+
+ /**
+ * Adds a @p documentation to the annotation.
+ *
+ * The documentation is meant to be read by human being, e.g. additional
+ * constraints or information about schema components.
+ */
+ void addDocumentation(const XsdDocumentation::Ptr &documentation);
+
+ /**
+ * Returns the list of all documentations of the annotation.
+ */
+ XsdDocumentation::List documentation() const;
+
+ private:
+ DerivedString<TypeID>::Ptr m_id;
+ XsdApplicationInformation::List m_applicationInformation;
+ XsdDocumentation::List m_documentations;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation.cpp b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp
new file mode 100644
index 0000000..45c6391
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdapplicationinformation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdApplicationInformation::setSource(const AnyURI::Ptr &source)
+{
+ m_source = source;
+}
+
+AnyURI::Ptr XsdApplicationInformation::source() const
+{
+ return m_source;
+}
+
+void XsdApplicationInformation::setContent(const QString &content)
+{
+ m_content = content;
+}
+
+QString XsdApplicationInformation::content() const
+{
+ return m_content;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation_p.h b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h
new file mode 100644
index 0000000..1a549cb
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdApplicationInformation_H
+#define Patternist_XsdApplicationInformation_H
+
+#include "qanytype_p.h"
+#include "qanyuri_p.h"
+#include "qnamedschemacomponent_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD appinfo object.
+ *
+ * This class represents the <em>appinfo</em> component of an <em>annotation</em> object
+ * of a XML schema as described <a href="http://www.w3.org/TR/xmlschema11-1/#cAnnotations">here</a>.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdApplicationInformation : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdApplicationInformation> Ptr;
+ typedef QList<XsdApplicationInformation::Ptr> List;
+
+ /**
+ * Sets the @p source of the application information.
+ *
+ * The source points to an URL that contains more
+ * information.
+ */
+ void setSource(const AnyURI::Ptr &source);
+
+ /**
+ * Returns the source of the application information.
+ */
+ AnyURI::Ptr source() const;
+
+ /**
+ * Sets the @p content of the application information.
+ *
+ * The content can be of abritrary type.
+ */
+ void setContent(const QString &content);
+
+ /**
+ * Returns the content of the application information.
+ */
+ QString content() const;
+
+ private:
+ AnyURI::Ptr m_source;
+ QString m_content;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdassertion.cpp b/src/xmlpatterns/schema/qxsdassertion.cpp
new file mode 100644
index 0000000..2f2d8aa
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdassertion.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdassertion_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAssertion::setTest(const XsdXPathExpression::Ptr &test)
+{
+ m_test = test;
+}
+
+XsdXPathExpression::Ptr XsdAssertion::test() const
+{
+ return m_test;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdassertion_p.h b/src/xmlpatterns/schema/qxsdassertion_p.h
new file mode 100644
index 0000000..c511c85
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdassertion_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAssertion_H
+#define Patternist_XsdAssertion_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdxpathexpression_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD assertion object.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#cAssertions">Assertion Definition</a>
+ */
+ class XsdAssertion : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAssertion> Ptr;
+ typedef QList<XsdAssertion::Ptr> List;
+
+ /**
+ * Sets the @p test of the assertion.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#as-test">Test Definition</a>
+ */
+ void setTest(const XsdXPathExpression::Ptr &test);
+
+ /**
+ * Returns the test of the assertion.
+ */
+ XsdXPathExpression::Ptr test() const;
+
+ private:
+ XsdXPathExpression::Ptr m_test;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattribute.cpp b/src/xmlpatterns/schema/qxsdattribute.cpp
new file mode 100644
index 0000000..68f9e3d
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattribute.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattribute_p.h"
+#include "qxsdcomplextype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+
+void XsdAttribute::Scope::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdAttribute::Scope::Variety XsdAttribute::Scope::variety() const
+{
+ return m_variety;
+}
+
+void XsdAttribute::Scope::setParent(const NamedSchemaComponent::Ptr &parent)
+{
+ m_parent = parent;
+}
+
+NamedSchemaComponent::Ptr XsdAttribute::Scope::parent() const
+{
+ return m_parent;
+}
+
+void XsdAttribute::ValueConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdAttribute::ValueConstraint::Variety XsdAttribute::ValueConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdAttribute::ValueConstraint::setValue(const QString &value)
+{
+ m_value = value;
+}
+
+QString XsdAttribute::ValueConstraint::value() const
+{
+ return m_value;
+}
+
+void XsdAttribute::ValueConstraint::setLexicalForm(const QString &form)
+{
+ m_lexicalForm = form;
+}
+
+QString XsdAttribute::ValueConstraint::lexicalForm() const
+{
+ return m_lexicalForm;
+}
+
+void XsdAttribute::setType(const AnySimpleType::Ptr &type)
+{
+ m_type = type;
+}
+
+AnySimpleType::Ptr XsdAttribute::type() const
+{
+ return m_type;
+}
+
+void XsdAttribute::setScope(const Scope::Ptr &scope)
+{
+ m_scope = scope;
+}
+
+XsdAttribute::Scope::Ptr XsdAttribute::scope() const
+{
+ return m_scope;
+}
+
+void XsdAttribute::setValueConstraint(const ValueConstraint::Ptr &constraint)
+{
+ m_valueConstraint = constraint;
+}
+
+XsdAttribute::ValueConstraint::Ptr XsdAttribute::valueConstraint() const
+{
+ return m_valueConstraint;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattribute_p.h b/src/xmlpatterns/schema/qxsdattribute_p.h
new file mode 100644
index 0000000..d64d335
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattribute_p.h
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAttribute_H
+#define Patternist_XsdAttribute_H
+
+#include "qanysimpletype_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD attribute object.
+ *
+ * This class represents the <em>attribute</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAttribute_Declarations">here</a>.
+ *
+ * It contains information from either a top-level attribute declaration (as child of
+ * a <em>schema</em> object) or of a local attribute declaration (as child of <em>complexType</em>
+ * or <em>attributeGroup</em> object without a 'ref' attribute).
+ *
+ * All other occurrences of the <em>attribute</em> object are represented by the XsdAttributeUse class.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSAttributeDeclaration">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttribute : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttribute> Ptr;
+ typedef QList<XsdAttribute::Ptr> List;
+
+ /**
+ * @short Describes the scope of an attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_a">Scope Definition</a>
+ */
+ class Scope : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<Scope> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ad-scope">scope</a> of an attribute.
+ */
+ enum Variety
+ {
+ Global, ///< The attribute is defined globally as child of the <em>schema</em> object.
+ Local ///< The attribute is defined locally as child of a complex type or attribute group definition.
+ };
+
+ /**
+ * Sets the @p variety of the attribute scope.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_a-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the attribute scope.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p parent complex type or attribute group definition of the attribute scope.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_a-parent">Parent Definition</a>
+ */
+ void setParent(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * Returns the parent complex type or attribute group definition of the attribute scope.
+ */
+ NamedSchemaComponent::Ptr parent() const;
+
+ private:
+ Variety m_variety;
+ NamedSchemaComponent::Ptr m_parent;
+ };
+
+
+ /**
+ * @short Describes the value constraint of an attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a">Value Constraint Definition</a>
+ */
+ class ValueConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ValueConstraint> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ad-value_constraint">value constraint</a> of an attribute.
+ */
+ enum Variety
+ {
+ Default, ///< The attribute has a default value set.
+ Fixed ///< The attribute has a fixed value set.
+ };
+
+ /**
+ * Sets the @p variety of the attribute value constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the attribute value constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p value of the constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a-value">Value Definition</a>
+ */
+ void setValue(const QString &value);
+
+ /**
+ * Returns the value of the constraint.
+ */
+ QString value() const;
+
+ /**
+ * Sets the lexical @p form of the constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a-lexical_form">Lexical Form Definition</a>
+ */
+ void setLexicalForm(const QString &form);
+
+ /**
+ * Returns the lexical form of the constraint.
+ */
+ QString lexicalForm() const;
+
+ private:
+ Variety m_variety;
+ QString m_value;
+ QString m_lexicalForm;
+ };
+
+ /**
+ * Sets the simple @p type definition of the attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ad-type_definition">Simple Type Definition</a>
+ */
+ void setType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the simple type definition of the attribute.
+ */
+ AnySimpleType::Ptr type() const;
+
+ /**
+ * Sets the @p scope of the attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ad-scope">Scope Definition</a>
+ */
+ void setScope(const Scope::Ptr &scope);
+
+ /**
+ * Returns the scope of the attribute.
+ */
+ Scope::Ptr scope() const;
+
+ /**
+ * Sets the value @p constraint of the attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ad-value_constraint">Value Constraint Definition</a>
+ */
+ void setValueConstraint(const ValueConstraint::Ptr &constraint);
+
+ /**
+ * Returns the value constraint of the attribute.
+ */
+ ValueConstraint::Ptr valueConstraint() const;
+
+ private:
+ AnySimpleType::Ptr m_type;
+ Scope::Ptr m_scope;
+ ValueConstraint::Ptr m_valueConstraint;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributegroup.cpp b/src/xmlpatterns/schema/qxsdattributegroup.cpp
new file mode 100644
index 0000000..b0dbc8a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributegroup.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributegroup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAttributeGroup::setAttributeUses(const XsdAttributeUse::List &attributeUses)
+{
+ m_attributeUses = attributeUses;
+}
+
+void XsdAttributeGroup::addAttributeUse(const XsdAttributeUse::Ptr &attributeUse)
+{
+ m_attributeUses.append(attributeUse);
+}
+
+XsdAttributeUse::List XsdAttributeGroup::attributeUses() const
+{
+ return m_attributeUses;
+}
+
+void XsdAttributeGroup::setWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ m_wildcard = wildcard;
+}
+
+XsdWildcard::Ptr XsdAttributeGroup::wildcard() const
+{
+ return m_wildcard;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributegroup_p.h b/src/xmlpatterns/schema/qxsdattributegroup_p.h
new file mode 100644
index 0000000..0d76d53
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributegroup_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAttributeGroup_H
+#define Patternist_XsdAttributeGroup_H
+
+#include "qxsdannotated_p.h"
+#include "qxsdattributeuse_p.h"
+#include "qxsdwildcard_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents the XSD attributeGroup object.
+ *
+ * This class represents the <em>attributeGroup</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAttribute_Group_Definitions">here</a>.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSAttributeGroup">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeGroup : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeGroup> Ptr;
+ typedef QList<XsdAttributeGroup::Ptr> List;
+
+ /**
+ * Sets the list of attribute @p uses that are defined in the attribute group.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#agd-attribute_uses">Attribute Uses</a>
+ */
+ void setAttributeUses(const XsdAttributeUse::List &uses);
+
+ /**
+ * Adds a new attribute @p use to the attribute group.
+ */
+ void addAttributeUse(const XsdAttributeUse::Ptr &use);
+
+ /**
+ * Returns the list of all attribute uses of the attribute group.
+ */
+ XsdAttributeUse::List attributeUses() const;
+
+ /**
+ * Sets the attribute @p wildcard of the attribute group.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#agd-attribute_wildcard">Attribute Wildcard</a>
+ */
+ void setWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Returns the attribute wildcard of the attribute group.
+ */
+ XsdWildcard::Ptr wildcard() const;
+
+ private:
+ XsdAttributeUse::List m_attributeUses;
+ XsdWildcard::Ptr m_wildcard;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributereference.cpp b/src/xmlpatterns/schema/qxsdattributereference.cpp
new file mode 100644
index 0000000..853705a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributereference.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdAttributeReference::isAttributeUse() const
+{
+ return false;
+}
+
+bool XsdAttributeReference::isReference() const
+{
+ return true;
+}
+
+void XsdAttributeReference::setType(Type type)
+{
+ m_type = type;
+}
+
+XsdAttributeReference::Type XsdAttributeReference::type() const
+{
+ return m_type;
+}
+
+void XsdAttributeReference::setReferenceName(const QXmlName &referenceName)
+{
+ m_referenceName = referenceName;
+}
+
+QXmlName XsdAttributeReference::referenceName() const
+{
+ return m_referenceName;
+}
+
+void XsdAttributeReference::setSourceLocation(const QSourceLocation &location)
+{
+ m_sourceLocation = location;
+}
+
+QSourceLocation XsdAttributeReference::sourceLocation() const
+{
+ return m_sourceLocation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributereference_p.h b/src/xmlpatterns/schema/qxsdattributereference_p.h
new file mode 100644
index 0000000..9c3ef80
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributereference_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAttributeReference_H
+#define Patternist_XsdAttributeReference_H
+
+#include "qxsdattributeuse_p.h"
+
+#include <QtXmlPatterns/QSourceLocation>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class for attribute reference resolving.
+ *
+ * For easy resolving of attribute references, we have this class
+ * that can be used as a place holder for the real attribute use
+ * object it is referring to.
+ * So whenever the parser detects an attribute reference, it creates
+ * a XsdAttributeReference and returns it instead of the XsdAttributeUse.
+ * During a later phase, the resolver will look for all XsdAttributeReferences
+ * in the schema and will replace them with their referring XsdAttributeUse
+ * objects.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeReference : public XsdAttributeUse
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeReference> Ptr;
+
+ /**
+ * Describes the type of the attribute reference.
+ */
+ enum Type
+ {
+ AttributeUse, ///< The reference points to an attribute use.
+ AttributeGroup ///< The reference points to an attribute group.
+ };
+
+ /**
+ * Always returns false, used to avoid dynamic casts.
+ */
+ virtual bool isAttributeUse() const;
+
+ /**
+ * Always returns true, used to avoid dynamic casts.
+ */
+ virtual bool isReference() const;
+
+ /**
+ * Sets the @p type of the attribute reference.
+ */
+ void setType(Type type);
+
+ /**
+ * Returns the type of the attribute reference.
+ */
+ Type type() const;
+
+ /**
+ * Sets the @p name of the attribute or attribute group the
+ * attribute reference refers to.
+ */
+ void setReferenceName(const QXmlName &name);
+
+ /**
+ * Returns the name of the attribute or attribute group the
+ * attribute reference refers to.
+ */
+ QXmlName referenceName() const;
+
+ /**
+ * Sets the source @p location where the reference is located.
+ */
+ void setSourceLocation(const QSourceLocation &location);
+
+ /**
+ * Returns the source location where the reference is located.
+ */
+ QSourceLocation sourceLocation() const;
+
+ private:
+ Type m_type;
+ QXmlName m_referenceName;
+ QSourceLocation m_sourceLocation;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributeterm.cpp b/src/xmlpatterns/schema/qxsdattributeterm.cpp
new file mode 100644
index 0000000..afed862
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeterm.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributeterm_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdAttributeTerm::isAttributeUse() const
+{
+ return false;
+}
+
+bool XsdAttributeTerm::isReference() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributeterm_p.h b/src/xmlpatterns/schema/qxsdattributeterm_p.h
new file mode 100644
index 0000000..45f5402
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeterm_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAttributeTerm_H
+#define Patternist_XsdAttributeTerm_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A base class for all attribute types.
+ *
+ * For easy resolving of attribute references, we use this as
+ * common base class for XsdAttribute and XsdAttributeReference.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeTerm : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeTerm> Ptr;
+
+ /**
+ * Returns @c true if the term is an attribute use, @c false otherwise.
+ */
+ virtual bool isAttributeUse() const;
+
+ /**
+ * Returns @c true if the term is an attribute use reference, @c false otherwise.
+ *
+ * @note The reference term is only used internally as helper during type resolving.
+ */
+ virtual bool isReference() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributeuse.cpp b/src/xmlpatterns/schema/qxsdattributeuse.cpp
new file mode 100644
index 0000000..4055d48
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeuse.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributeuse_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAttributeUse::ValueConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdAttributeUse::ValueConstraint::Variety XsdAttributeUse::ValueConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdAttributeUse::ValueConstraint::setValue(const QString &value)
+{
+ m_value = value;
+}
+
+QString XsdAttributeUse::ValueConstraint::value() const
+{
+ return m_value;
+}
+
+void XsdAttributeUse::ValueConstraint::setLexicalForm(const QString &form)
+{
+ m_lexicalForm = form;
+}
+
+QString XsdAttributeUse::ValueConstraint::lexicalForm() const
+{
+ return m_lexicalForm;
+}
+
+XsdAttributeUse::ValueConstraint::Ptr XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(const XsdAttribute::ValueConstraint::Ptr &constraint)
+{
+ XsdAttributeUse::ValueConstraint::Ptr newConstraint(new XsdAttributeUse::ValueConstraint());
+ switch (constraint->variety()) {
+ case XsdAttribute::ValueConstraint::Fixed: newConstraint->setVariety(Fixed); break;
+ case XsdAttribute::ValueConstraint::Default: newConstraint->setVariety(Default); break;
+ }
+ newConstraint->setValue(constraint->value());
+ newConstraint->setLexicalForm(constraint->lexicalForm());
+
+ return newConstraint;
+}
+
+XsdAttributeUse::XsdAttributeUse()
+ : m_useType(OptionalUse)
+{
+}
+
+bool XsdAttributeUse::isAttributeUse() const
+{
+ return true;
+}
+
+void XsdAttributeUse::setUseType(UseType type)
+{
+ m_useType = type;
+}
+
+XsdAttributeUse::UseType XsdAttributeUse::useType() const
+{
+ return m_useType;
+}
+
+bool XsdAttributeUse::isRequired() const
+{
+ return (m_useType == RequiredUse);
+}
+
+void XsdAttributeUse::setAttribute(const XsdAttribute::Ptr &attribute)
+{
+ m_attribute = attribute;
+}
+
+XsdAttribute::Ptr XsdAttributeUse::attribute() const
+{
+ return m_attribute;
+}
+
+void XsdAttributeUse::setValueConstraint(const ValueConstraint::Ptr &constraint)
+{
+ m_valueConstraint = constraint;
+}
+
+XsdAttributeUse::ValueConstraint::Ptr XsdAttributeUse::valueConstraint() const
+{
+ return m_valueConstraint;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributeuse_p.h b/src/xmlpatterns/schema/qxsdattributeuse_p.h
new file mode 100644
index 0000000..648620f
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeuse_p.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdAttributeUse_H
+#define Patternist_XsdAttributeUse_H
+
+#include "qxsdattribute_p.h"
+#include "qxsdattributeterm_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD attribute use object.
+ *
+ * This class represents the <em>attribute use</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAttributeUse">here</a>.
+ *
+ * It contains information from a local attribute declaration (as child of <em>complexType</em>
+ * or <em>attributeGroup</em> object).
+ *
+ * All other occurrences of the <em>attribute</em> object are represented by the XsdAttribute class.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSAttributeUse">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeUse : public XsdAttributeTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeUse> Ptr;
+ typedef QList<XsdAttributeUse::Ptr> List;
+
+ /**
+ * Describes the value constraint of an attribute use.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_au">Value Constraint Definition</a>
+ */
+ class ValueConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ValueConstraint> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#au-value_constraint">value constraint</a> of an attribute use.
+ */
+ enum Variety
+ {
+ Default, ///< The attribute use has a default value set.
+ Fixed ///< The attribute use has a fixed value set.
+ };
+
+ /**
+ * Sets the @p variety of the attribute use value constraint.
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the attribute use value constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p value of the constraint.
+ */
+ void setValue(const QString &value);
+
+ /**
+ * Returns the value of the constraint.
+ */
+ QString value() const;
+
+ /**
+ * Sets the lexical @p form of the constraint.
+ */
+ void setLexicalForm(const QString &form);
+
+ /**
+ * Returns the lexical form of the constraint.
+ */
+ QString lexicalForm() const;
+
+ /**
+ * Creates a new value constraint from a XsdAttribute::ValueConstraint.
+ */
+ static ValueConstraint::Ptr fromAttributeValueConstraint(const XsdAttribute::ValueConstraint::Ptr &constraint);
+
+ private:
+ Variety m_variety;
+ QString m_value;
+ QString m_lexicalForm;
+ };
+
+ /**
+ * Describes the use type of the attribute use.
+ */
+ enum UseType
+ {
+ OptionalUse, ///< The attribute can be there but doesn't need to.
+ RequiredUse, ///< The attribute must be there.
+ ProhibitedUse ///< The attribute is not allowed to be there.
+ };
+
+ /**
+ * Creates a new attribute use object.
+ */
+ XsdAttributeUse();
+
+ /**
+ * Always returns true, used to avoid dynamic casts.
+ */
+ virtual bool isAttributeUse() const;
+
+ /**
+ * Sets the use @p type of the attribute use.
+ *
+ * @see UseType
+ */
+ void setUseType(UseType type);
+
+ /**
+ * Returns the use type of the attribute use.
+ */
+ UseType useType() const;
+
+ /**
+ * Returns whether the attribute use is required.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#au-required">Required Definition</a>
+ */
+ bool isRequired() const;
+
+ /**
+ * Sets the @p attribute the attribute use is referring to.
+ * That is either a local definition as child of a complexType
+ * or attributeGroup object, or a reference defined by the
+ * 'ref' attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#au-attribute_declaration">Attribute Declaration</a>
+ */
+ void setAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Returns the attribute the attribute use is referring to.
+ */
+ XsdAttribute::Ptr attribute() const;
+
+ /**
+ * Sets the value @p constraint of the attribute use.
+ *
+ * @see http://www.w3.org/TR/xmlschema11-1/#vc_au
+ */
+ void setValueConstraint(const ValueConstraint::Ptr &constraint);
+
+ /**
+ * Returns the value constraint of the attribute use.
+ */
+ ValueConstraint::Ptr valueConstraint() const;
+
+ private:
+ UseType m_useType;
+ XsdAttribute::Ptr m_attribute;
+ ValueConstraint::Ptr m_valueConstraint;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp
new file mode 100644
index 0000000..42aeb60
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdcomplextype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdComplexType::OpenContent::setMode(Mode mode)
+{
+ m_mode = mode;
+}
+
+XsdComplexType::OpenContent::Mode XsdComplexType::OpenContent::mode() const
+{
+ return m_mode;
+}
+
+void XsdComplexType::OpenContent::setWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ m_wildcard = wildcard;
+}
+
+XsdWildcard::Ptr XsdComplexType::OpenContent::wildcard() const
+{
+ return m_wildcard;
+}
+
+void XsdComplexType::ContentType::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdComplexType::ContentType::Variety XsdComplexType::ContentType::variety() const
+{
+ return m_variety;
+}
+
+void XsdComplexType::ContentType::setParticle(const XsdParticle::Ptr &particle)
+{
+ m_particle = particle;
+}
+
+XsdParticle::Ptr XsdComplexType::ContentType::particle() const
+{
+ return m_particle;
+}
+
+void XsdComplexType::ContentType::setOpenContent(const OpenContent::Ptr &content)
+{
+ m_openContent = content;
+}
+
+XsdComplexType::OpenContent::Ptr XsdComplexType::ContentType::openContent() const
+{
+ return m_openContent;
+}
+
+void XsdComplexType::ContentType::setSimpleType(const AnySimpleType::Ptr &type)
+{
+ m_simpleType = type;
+}
+
+AnySimpleType::Ptr XsdComplexType::ContentType::simpleType() const
+{
+ return m_simpleType;
+}
+
+
+XsdComplexType::XsdComplexType()
+ : m_isAbstract(false)
+ , m_contentType(new ContentType())
+{
+ m_contentType->setVariety(ContentType::Empty);
+}
+
+void XsdComplexType::setIsAbstract(bool abstract)
+{
+ m_isAbstract = abstract;
+}
+
+bool XsdComplexType::isAbstract() const
+{
+ return m_isAbstract;
+}
+
+QString XsdComplexType::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(name(np));
+}
+
+void XsdComplexType::setWxsSuperType(const SchemaType::Ptr &type)
+{
+ m_superType = type;
+}
+
+SchemaType::Ptr XsdComplexType::wxsSuperType() const
+{
+ return m_superType;
+}
+
+void XsdComplexType::setContext(const NamedSchemaComponent::Ptr &component)
+{
+ m_context = component;
+}
+
+NamedSchemaComponent::Ptr XsdComplexType::context() const
+{
+ return m_context;
+}
+
+void XsdComplexType::setContentType(const ContentType::Ptr &type)
+{
+ m_contentType = type;
+}
+
+XsdComplexType::ContentType::Ptr XsdComplexType::contentType() const
+{
+ return m_contentType;
+}
+
+void XsdComplexType::setAttributeUses(const XsdAttributeUse::List &attributeUses)
+{
+ m_attributeUses = attributeUses;
+}
+
+void XsdComplexType::addAttributeUse(const XsdAttributeUse::Ptr &attributeUse)
+{
+ m_attributeUses.append(attributeUse);
+}
+
+XsdAttributeUse::List XsdComplexType::attributeUses() const
+{
+ return m_attributeUses;
+}
+
+void XsdComplexType::setAttributeWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ m_attributeWildcard = wildcard;
+}
+
+XsdWildcard::Ptr XsdComplexType::attributeWildcard() const
+{
+ return m_attributeWildcard;
+}
+
+XsdComplexType::TypeCategory XsdComplexType::category() const
+{
+ return ComplexType;
+}
+
+void XsdComplexType::setDerivationMethod(DerivationMethod method)
+{
+ m_derivationMethod = method;
+}
+
+XsdComplexType::DerivationMethod XsdComplexType::derivationMethod() const
+{
+ return m_derivationMethod;
+}
+
+void XsdComplexType::setProhibitedSubstitutions(const BlockingConstraints &substitutions)
+{
+ m_prohibitedSubstitutions = substitutions;
+}
+
+XsdComplexType::BlockingConstraints XsdComplexType::prohibitedSubstitutions() const
+{
+ return m_prohibitedSubstitutions;
+}
+
+void XsdComplexType::setAssertions(const XsdAssertion::List &assertions)
+{
+ m_assertions = assertions;
+}
+
+void XsdComplexType::addAssertion(const XsdAssertion::Ptr &assertion)
+{
+ m_assertions.append(assertion);
+}
+
+XsdAssertion::List XsdComplexType::assertions() const
+{
+ return m_assertions;
+}
+
+bool XsdComplexType::isDefinedBySchema() const
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h
new file mode 100644
index 0000000..d28d2fc
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdComplexType_H
+#define Patternist_XsdComplexType_H
+
+#include "qanytype_p.h"
+#include "qxsdassertion_p.h"
+#include "qxsdattributeuse_p.h"
+#include "qxsdparticle_p.h"
+#include "qxsdsimpletype_p.h"
+#include "qxsduserschematype_p.h"
+#include "qxsdwildcard_p.h"
+
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD complexType object.
+ *
+ * This class represents the <em>complexType</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#Complex_Type_Definitions">here</a>.
+ *
+ * It contains information from either a top-level complex type declaration (as child of a <em>schema</em> object)
+ * or a local complex type declaration (as descendant of an <em>element</em> object).
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSComplexType">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdComplexType : public XsdUserSchemaType<AnyType>
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdComplexType> Ptr;
+
+ /**
+ * @short Describes the open content object of a complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-open_content">Open Content Definition</a>
+ */
+ class OpenContent : public QSharedData, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<OpenContent> Ptr;
+
+ /**
+ * Describes the mode of the open content.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#oc-mode">Mode Definition</a>
+ */
+ enum Mode
+ {
+ None,
+ Interleave,
+ Suffix
+ };
+
+ /**
+ * Sets the @p mode of the open content.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#oc-mode">Mode Definition</a>
+ */
+ void setMode(Mode mode);
+
+ /**
+ * Returns the mode of the open content.
+ */
+ Mode mode() const;
+
+ /**
+ * Sets the @p wildcard of the open content.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#oc-wildcard">Wildcard Definition</a>
+ */
+ void setWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Returns the wildcard of the open content.
+ */
+ XsdWildcard::Ptr wildcard() const;
+
+ private:
+ Mode m_mode;
+ XsdWildcard::Ptr m_wildcard;
+ };
+
+ /**
+ * @short Describes the content type of a complex type.
+ */
+ class ContentType : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ContentType> Ptr;
+
+ /**
+ * Describes the variety of the content type.
+ */
+ enum Variety
+ {
+ Empty = 0, ///< The complex type has no further content.
+ Simple, ///< The complex type has only simple type content (e.g. text, number etc.)
+ ElementOnly, ///< The complex type has further elements or attributes but no text as content.
+ Mixed ///< The complex type has further elements or attributes and text as content.
+ };
+
+ /**
+ * Sets the @p variety of the content type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the content type.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p particle object of the content type.
+ *
+ * The content type has only a particle object if
+ * its variety is ElementOnly or Mixed.
+ *
+ * @see XsdParticle
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-particle">Particle Declaration</a>
+ */
+ void setParticle(const XsdParticle::Ptr &particle);
+
+ /**
+ * Returns the particle object of the content type,
+ * or an empty pointer if its variety is neither
+ * ElementOnly nor Mixed.
+ */
+ XsdParticle::Ptr particle() const;
+
+ /**
+ * Sets the open @p content object of the content type.
+ *
+ * The content type has only an open content object if
+ * its variety is ElementOnly or Mixed.
+ *
+ * @see OpenContent
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-open_content">Open Content Declaration</a>
+ */
+ void setOpenContent(const OpenContent::Ptr &content);
+
+ /**
+ * Returns the open content object of the content type,
+ * or an empty pointer if its variety is neither
+ * ElementOnly nor Mixed.
+ */
+ OpenContent::Ptr openContent() const;
+
+ /**
+ * Sets the simple @p type object of the content type.
+ *
+ * The content type has only a simple type object if
+ * its variety is Simple.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-simple_type_definition">Simple Type Definition</a>
+ */
+ void setSimpleType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the simple type object of the content type,
+ * or an empty pointer if its variety is not Simple.
+ */
+ AnySimpleType::Ptr simpleType() const;
+
+ private:
+ Variety m_variety;
+ XsdParticle::Ptr m_particle;
+ OpenContent::Ptr m_openContent;
+ XsdSimpleType::Ptr m_simpleType;
+ };
+
+
+ /**
+ * Creates a complex type object with empty content.
+ */
+ XsdComplexType();
+
+ /**
+ * Destroys the complex type object.
+ */
+ ~XsdComplexType() {};
+
+ /**
+ * Returns the display name of the complex type.
+ *
+ * The display name can be used to show the type name
+ * to the user.
+ *
+ * @param namePool The name pool where the type name is stored in.
+ */
+ virtual QString displayName(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Sets the base type of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-base_type_definition">Base Type Definition</a>
+ */
+ void setWxsSuperType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the base type of the complex type.
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * Sets the context @p component of the complex type.
+ *
+ * The component is either an element declaration or a complex type definition.
+ */
+ void setContext(const NamedSchemaComponent::Ptr &component);
+
+ /**
+ * Returns the context component of the complex type.
+ */
+ NamedSchemaComponent::Ptr context() const;
+
+ /**
+ * Sets the derivation @p method of the complex type.
+ *
+ * The derivation method depends on whether the complex
+ * type object has an extension or restriction object as child.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-derivation_method">Derivation Method Definition</a>
+ * @see DerivationMethod
+ */
+ void setDerivationMethod(DerivationMethod method);
+
+ /**
+ * Returns the derivation method of the complex type.
+ */
+ virtual DerivationMethod derivationMethod() const;
+
+ /**
+ * Sets whether the complex type is @p abstract.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-abstract">Abstract Definition</a>
+ */
+ void setIsAbstract(bool abstract);
+
+ /**
+ * Returns whether the complex type is abstract.
+ */
+ virtual bool isAbstract() const;
+
+ /**
+ * Sets the list of all attribute @p uses of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-attribute_uses">Attribute Uses Declaration</a>
+ */
+ void setAttributeUses(const XsdAttributeUse::List &uses);
+
+ /**
+ * Adds a new attribute @p use to the complex type.
+ */
+ void addAttributeUse(const XsdAttributeUse::Ptr &use);
+
+ /**
+ * Returns the list of all attribute uses of the complex type.
+ */
+ XsdAttributeUse::List attributeUses() const;
+
+ /**
+ * Sets the attribute @p wildcard of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-attribute_wildcard">Attribute Wildcard Declaration</a>
+ */
+ void setAttributeWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Returns the attribute wildcard of the complex type.
+ */
+ XsdWildcard::Ptr attributeWildcard() const;
+
+ /**
+ * Always returns SchemaType::ComplexType
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * Sets the content @p type of the complex type.
+ *
+ * @see ContentType
+ */
+ void setContentType(const ContentType::Ptr &type);
+
+ /**
+ * Returns the content type of the complex type.
+ */
+ ContentType::Ptr contentType() const;
+
+ /**
+ * Sets the prohibited @p substitutions of the complex type.
+ *
+ * Only ExtensionConstraint and RestrictionConstraint are allowed.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-prohibited_substitutions">Prohibited Substitutions Definition</a>
+ */
+ void setProhibitedSubstitutions(const BlockingConstraints &substitutions);
+
+ /**
+ * Returns the prohibited substitutions of the complex type.
+ */
+ BlockingConstraints prohibitedSubstitutions() const;
+
+ /**
+ * Sets the @p assertions of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-assertions">Assertions Definition</a>
+ */
+ void setAssertions(const XsdAssertion::List &assertions);
+
+ /**
+ * Adds an @p assertion to the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-assertions">Assertions Definition</a>
+ */
+ void addAssertion(const XsdAssertion::Ptr &assertion);
+
+ /**
+ * Returns the assertions of the complex type.
+ */
+ XsdAssertion::List assertions() const;
+
+ /**
+ * Always returns @c true.
+ */
+ virtual bool isDefinedBySchema() const;
+
+ private:
+ SchemaType::Ptr m_superType;
+ NamedSchemaComponent::Ptr m_context;
+ DerivationMethod m_derivationMethod;
+ bool m_isAbstract;
+ XsdAttributeUse::List m_attributeUses;
+ XsdWildcard::Ptr m_attributeWildcard;
+ ContentType::Ptr m_contentType;
+ BlockingConstraints m_prohibitedSubstitutions;
+ XsdAssertion::List m_assertions;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsddocumentation.cpp b/src/xmlpatterns/schema/qxsddocumentation.cpp
new file mode 100644
index 0000000..de610b4
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsddocumentation.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsddocumentation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdDocumentation::XsdDocumentation()
+{
+}
+
+XsdDocumentation::~XsdDocumentation()
+{
+}
+
+void XsdDocumentation::setSource(const AnyURI::Ptr &source)
+{
+ m_source = source;
+}
+
+AnyURI::Ptr XsdDocumentation::source() const
+{
+ return m_source;
+}
+
+void XsdDocumentation::setLanguage(const DerivedString<TypeLanguage>::Ptr &language)
+{
+ m_language = language;
+}
+
+DerivedString<TypeLanguage>::Ptr XsdDocumentation::language() const
+{
+ return m_language;
+}
+
+void XsdDocumentation::setContent(const QString &content)
+{
+ m_content = content;
+}
+
+QString XsdDocumentation::content() const
+{
+ return m_content;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsddocumentation_p.h b/src/xmlpatterns/schema/qxsddocumentation_p.h
new file mode 100644
index 0000000..cdccfd7
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsddocumentation_p.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdDocumentation_H
+#define Patternist_XsdDocumentation_H
+
+#include "qanytype_p.h"
+#include "qanyuri_p.h"
+#include "qderivedstring_p.h"
+#include "qnamedschemacomponent_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD documentation object.
+ *
+ * This class represents the <em>documentation</em> component of an <em>annotation</em> object
+ * of a XML schema as described <a href="http://www.w3.org/TR/xmlschema11-1/#cAnnotations">here</a>.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdDocumentation : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdDocumentation> Ptr;
+ typedef QList<XsdDocumentation::Ptr> List;
+
+ /**
+ * Creates a new documentation object.
+ */
+ XsdDocumentation();
+
+ /**
+ * Destroys the documentation object.
+ */
+ ~XsdDocumentation();
+
+ /**
+ * Sets the @p source of the documentation.
+ *
+ * The source points to an URL that contains more
+ * information.
+ */
+ void setSource(const AnyURI::Ptr &source);
+
+ /**
+ * Returns the source of the documentation.
+ */
+ AnyURI::Ptr source() const;
+
+ /**
+ * Sets the @p language of the documentation.
+ */
+ void setLanguage(const DerivedString<TypeLanguage>::Ptr &language);
+
+ /**
+ * Returns the language of the documentation.
+ */
+ DerivedString<TypeLanguage>::Ptr language() const;
+
+ /**
+ * Sets the @p content of the documentation.
+ *
+ * The content can be of abritrary type.
+ */
+ void setContent(const QString &content);
+
+ /**
+ * Returns the content of the documentation.
+ */
+ QString content() const;
+
+ private:
+ AnyURI::Ptr m_source;
+ DerivedString<TypeLanguage>::Ptr m_language;
+ QString m_content;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp
new file mode 100644
index 0000000..1ebec06
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdelement.cpp
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdelement_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdElement::Scope::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdElement::Scope::Variety XsdElement::Scope::variety() const
+{
+ return m_variety;
+}
+
+void XsdElement::Scope::setParent(const NamedSchemaComponent::Ptr &parent)
+{
+ m_parent = parent;
+}
+
+NamedSchemaComponent::Ptr XsdElement::Scope::parent() const
+{
+ return m_parent;
+}
+
+void XsdElement::ValueConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdElement::ValueConstraint::Variety XsdElement::ValueConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdElement::ValueConstraint::setValue(const QString &value)
+{
+ m_value = value;
+}
+
+QString XsdElement::ValueConstraint::value() const
+{
+ return m_value;
+}
+
+void XsdElement::ValueConstraint::setLexicalForm(const QString &form)
+{
+ m_lexicalForm = form;
+}
+
+QString XsdElement::ValueConstraint::lexicalForm() const
+{
+ return m_lexicalForm;
+}
+
+void XsdElement::TypeTable::addAlternative(const XsdAlternative::Ptr &alternative)
+{
+ m_alternatives.append(alternative);
+}
+
+XsdAlternative::List XsdElement::TypeTable::alternatives() const
+{
+ return m_alternatives;
+}
+
+void XsdElement::TypeTable::setDefaultTypeDefinition(const XsdAlternative::Ptr &type)
+{
+ m_defaultTypeDefinition = type;
+}
+
+XsdAlternative::Ptr XsdElement::TypeTable::defaultTypeDefinition() const
+{
+ return m_defaultTypeDefinition;
+}
+
+
+XsdElement::XsdElement()
+ : m_isAbstract(false)
+{
+}
+
+bool XsdElement::isElement() const
+{
+ return true;
+}
+
+void XsdElement::setType(const SchemaType::Ptr &type)
+{
+ m_type = type;
+}
+
+SchemaType::Ptr XsdElement::type() const
+{
+ return m_type;
+}
+
+void XsdElement::setScope(const Scope::Ptr &scope)
+{
+ m_scope = scope;
+}
+
+XsdElement::Scope::Ptr XsdElement::scope() const
+{
+ return m_scope;
+}
+
+void XsdElement::setValueConstraint(const ValueConstraint::Ptr &constraint)
+{
+ m_valueConstraint = constraint;
+}
+
+XsdElement::ValueConstraint::Ptr XsdElement::valueConstraint() const
+{
+ return m_valueConstraint;
+}
+
+void XsdElement::setTypeTable(const TypeTable::Ptr &table)
+{
+ m_typeTable = table;
+}
+
+XsdElement::TypeTable::Ptr XsdElement::typeTable() const
+{
+ return m_typeTable;
+}
+
+void XsdElement::setIsAbstract(bool abstract)
+{
+ m_isAbstract = abstract;
+}
+
+bool XsdElement::isAbstract() const
+{
+ return m_isAbstract;
+}
+
+void XsdElement::setIsNillable(bool nillable)
+{
+ m_isNillable = nillable;
+}
+
+bool XsdElement::isNillable() const
+{
+ return m_isNillable;
+}
+
+void XsdElement::setDisallowedSubstitutions(const BlockingConstraints &substitutions)
+{
+ m_disallowedSubstitutions = substitutions;
+}
+
+XsdElement::BlockingConstraints XsdElement::disallowedSubstitutions() const
+{
+ return m_disallowedSubstitutions;
+}
+
+void XsdElement::setSubstitutionGroupExclusions(const SchemaType::DerivationConstraints &exclusions)
+{
+ m_substitutionGroupExclusions = exclusions;
+}
+
+SchemaType::DerivationConstraints XsdElement::substitutionGroupExclusions() const
+{
+ return m_substitutionGroupExclusions;
+}
+
+void XsdElement::setIdentityConstraints(const XsdIdentityConstraint::List &constraints)
+{
+ m_identityConstraints = constraints;
+}
+
+void XsdElement::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
+{
+ m_identityConstraints.append(constraint);
+}
+
+XsdIdentityConstraint::List XsdElement::identityConstraints() const
+{
+ return m_identityConstraints;
+}
+
+void XsdElement::setSubstitutionGroupAffiliations(const XsdElement::List &affiliations)
+{
+ m_substitutionGroupAffiliations = affiliations;
+}
+
+XsdElement::List XsdElement::substitutionGroupAffiliations() const
+{
+ return m_substitutionGroupAffiliations;
+}
+
+void XsdElement::addSubstitutionGroup(const XsdElement::Ptr &element)
+{
+ m_substitutionGroups.insert(element);
+}
+
+XsdElement::List XsdElement::substitutionGroups() const
+{
+ return m_substitutionGroups.toList();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h
new file mode 100644
index 0000000..93c5983
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdelement_p.h
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdElement_H
+#define Patternist_XsdElement_H
+
+#include "qschemacomponent_p.h"
+#include "qschematype_p.h"
+#include "qxsdalternative_p.h"
+#include "qxsdidentityconstraint_p.h"
+#include "qxsdcomplextype_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD element object.
+ *
+ * This class represents the <em>element</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cElement_Declarations">here</a>.
+ *
+ * It contains information from either a top-level element declaration (as child of a <em>schema</em> object)
+ * or a local element declaration (as descendant of an <em>complexType</em> object).
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSElementDecl">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdElement : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdElement> Ptr;
+ typedef QList<XsdElement::Ptr> List;
+
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ed-value_constraint">constraint type</a> of the element.
+ */
+ enum ConstraintType
+ {
+ NoneConstraint, ///< The value of the element has no constraints.
+ DefaultConstraint, ///< The element has a default value set.
+ FixedConstraint ///< The element has a fixed value set.
+ };
+
+ /**
+ * Describes the scope of an element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_e">Scope Definition</a>
+ */
+ class Scope : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<Scope> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ad-scope">scope</a> of an attribute.
+ */
+ enum Variety
+ {
+ Global, ///< The element is defined globally as child of the <em>schema</em> object.
+ Local ///< The element is defined locally as child of a complex type or model group definition.
+ };
+
+ /**
+ * Sets the @p variety of the element scope.
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the element scope.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p parent complex type or model group definition of the element scope.
+ */
+ void setParent(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * Returns the parent complex type or model group definition of the element scope.
+ */
+ NamedSchemaComponent::Ptr parent() const;
+
+ private:
+ Variety m_variety;
+ NamedSchemaComponent::Ptr m_parent;
+ };
+
+ /**
+ * Describes a type table of an element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#tt">Type Table Definition</a>
+ */
+ class TypeTable : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<TypeTable> Ptr;
+
+ /**
+ * Adds an @p alternative to the type table.
+ */
+ void addAlternative(const XsdAlternative::Ptr &alternative);
+
+ /**
+ * Returns the alternatives of the type table.
+ */
+ XsdAlternative::List alternatives() const;
+
+ /**
+ * Sets the default @p type definition.
+ */
+ void setDefaultTypeDefinition(const XsdAlternative::Ptr &type);
+
+ /**
+ * Returns the default type definition.
+ */
+ XsdAlternative::Ptr defaultTypeDefinition() const;
+
+ private:
+ XsdAlternative::List m_alternatives;
+ XsdAlternative::Ptr m_defaultTypeDefinition;
+ };
+
+
+ /**
+ * Describes the value constraint of an element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_e">Value Constraint Definition</a>
+ */
+ class ValueConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ValueConstraint> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ed-value_constraint">value constraint</a> of an element.
+ */
+ enum Variety
+ {
+ Default, ///< The element has a default value set.
+ Fixed ///< The element has a fixed value set.
+ };
+
+ /**
+ * Sets the @p variety of the element value constraint.
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the element value constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p value of the constraint.
+ */
+ void setValue(const QString &value);
+
+ /**
+ * Returns the value of the constraint.
+ */
+ QString value() const;
+
+ /**
+ * Sets the lexical @p form of the constraint.
+ */
+ void setLexicalForm(const QString &form);
+
+ /**
+ * Returns the lexical form of the constraint.
+ */
+ QString lexicalForm() const;
+
+ private:
+ Variety m_variety;
+ QString m_value;
+ QString m_lexicalForm;
+ };
+
+ /**
+ * Creates a new element object.
+ */
+ XsdElement();
+
+ /**
+ * Always returns @c true, used to avoid dynamic casts.
+ */
+ virtual bool isElement() const;
+
+ /**
+ * Sets the @p type of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-type_definition">Type Definition</a>
+ */
+ void setType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the type of the element.
+ */
+ SchemaType::Ptr type() const;
+
+ /**
+ * Sets the @p scope of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-scope">Scope Definition</a>
+ */
+ void setScope(const Scope::Ptr &scope);
+
+ /**
+ * Returns the scope of the element.
+ */
+ Scope::Ptr scope() const;
+
+ /**
+ * Sets the value @p constraint of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-value_constraint">Value Constraint Definition</a>
+ */
+ void setValueConstraint(const ValueConstraint::Ptr &constraint);
+
+ /**
+ * Returns the value constraint of the element.
+ */
+ ValueConstraint::Ptr valueConstraint() const;
+
+ /**
+ * Sets the type table of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-type_table">Type Table Definition</a>
+ */
+ void setTypeTable(const TypeTable::Ptr &table);
+
+ /**
+ * Returns the type table of the element.
+ */
+ TypeTable::Ptr typeTable() const;
+
+ /**
+ * Sets whether the element is @p abstract.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-abstract">Abstract Definition</a>
+ */
+ void setIsAbstract(bool abstract);
+
+ /**
+ * Returns whether the element is abstract.
+ */
+ bool isAbstract() const;
+
+ /**
+ * Sets whether the element is @p nillable.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-nillable">Nillable Definition</a>
+ */
+ void setIsNillable(bool nillable);
+
+ /**
+ * Returns whether the element is nillable.
+ */
+ bool isNillable() const;
+
+ /**
+ * Sets the disallowed @p substitutions of the element.
+ *
+ * Only ExtensionConstraint, RestrictionConstraint and SubstitutionConstraint are allowed.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-disallowed_substitutions">Disallowed Substitutions Definition</a>
+ */
+ void setDisallowedSubstitutions(const BlockingConstraints &substitutions);
+
+ /**
+ * Returns the disallowed substitutions of the element.
+ */
+ BlockingConstraints disallowedSubstitutions() const;
+
+ /**
+ * Sets the substitution group @p exclusions of the element.
+ *
+ * Only SchemaType::ExtensionConstraint and SchemaType::RestrictionConstraint are allowed.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-substitution_group_exclusions">Substitution Group Exclusions Definition</a>
+ */
+ void setSubstitutionGroupExclusions(const SchemaType::DerivationConstraints &exclusions);
+
+ /**
+ * Returns the substitution group exclusions of the element.
+ */
+ SchemaType::DerivationConstraints substitutionGroupExclusions() const;
+
+ /**
+ * Sets the identity @p constraints of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-identity-constraint_definitions">Identity Constraint Definition</a>
+ */
+ void setIdentityConstraints(const XsdIdentityConstraint::List &constraints);
+
+ /**
+ * Adds a new identity @p constraint to the element.
+ */
+ void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint);
+
+ /**
+ * Returns a list of all identity constraints of the element.
+ */
+ XsdIdentityConstraint::List identityConstraints() const;
+
+ /**
+ * Sets the substitution group @p affiliations of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-substituion_group_affiliations">Substitution Group Affiliations</a>
+ */
+ void setSubstitutionGroupAffiliations(const XsdElement::List &affiliations);
+
+ /**
+ * Returns the substitution group affiliations of the element.
+ */
+ XsdElement::List substitutionGroupAffiliations() const;
+
+ /**
+ * Adds a substitution group to the element.
+ */
+ void addSubstitutionGroup(const XsdElement::Ptr &elements);
+
+ /**
+ * Returns the substitution groups of the element.
+ */
+ XsdElement::List substitutionGroups() const;
+
+ private:
+ SchemaType::Ptr m_type;
+ Scope::Ptr m_scope;
+ ValueConstraint::Ptr m_valueConstraint;
+ TypeTable::Ptr m_typeTable;
+ bool m_isAbstract;
+ bool m_isNillable;
+ BlockingConstraints m_disallowedSubstitutions;
+ SchemaType::DerivationConstraints m_substitutionGroupExclusions;
+ XsdIdentityConstraint::List m_identityConstraints;
+ XsdElement::List m_substitutionGroupAffiliations;
+ QSet<XsdElement::Ptr> m_substitutionGroups;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdfacet.cpp b/src/xmlpatterns/schema/qxsdfacet.cpp
new file mode 100644
index 0000000..80acc74
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdfacet.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdfacet_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdFacet::XsdFacet()
+ : m_type(None)
+{
+}
+
+void XsdFacet::setType(Type type)
+{
+ m_type = type;
+}
+
+XsdFacet::Type XsdFacet::type() const
+{
+ return m_type;
+}
+
+void XsdFacet::setValue(const AtomicValue::Ptr &value)
+{
+ m_value = value;
+}
+
+AtomicValue::Ptr XsdFacet::value() const
+{
+ return m_value;
+}
+
+void XsdFacet::setMultiValue(const AtomicValue::List &value)
+{
+ m_multiValue = value;
+}
+
+AtomicValue::List XsdFacet::multiValue() const
+{
+ return m_multiValue;
+}
+
+void XsdFacet::setAssertions(const XsdAssertion::List &assertions)
+{
+ m_assertions = assertions;
+}
+
+XsdAssertion::List XsdFacet::assertions() const
+{
+ return m_assertions;
+}
+
+void XsdFacet::setFixed(bool fixed)
+{
+ m_fixed = fixed;
+}
+
+bool XsdFacet::fixed() const
+{
+ return m_fixed;
+}
+
+QString XsdFacet::typeName(Type type)
+{
+ switch (type) {
+ case Length: return QLatin1String("length"); break;
+ case MinimumLength: return QLatin1String("minLength"); break;
+ case MaximumLength: return QLatin1String("maxLength"); break;
+ case Pattern: return QLatin1String("pattern"); break;
+ case WhiteSpace: return QLatin1String("whiteSpace"); break;
+ case MaximumInclusive: return QLatin1String("maxInclusive"); break;
+ case MaximumExclusive: return QLatin1String("maxExclusive"); break;
+ case MinimumInclusive: return QLatin1String("minInclusive"); break;
+ case MinimumExclusive: return QLatin1String("minExclusive"); break;
+ case TotalDigits: return QLatin1String("totalDigits"); break;
+ case FractionDigits: return QLatin1String("fractionDigits"); break;
+ case Enumeration: return QLatin1String("enumeration"); break;
+ case Assertion: return QLatin1String("assertion"); break;
+ case None: // fall through
+ default: return QLatin1String("none"); break;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdfacet_p.h b/src/xmlpatterns/schema/qxsdfacet_p.h
new file mode 100644
index 0000000..349e211
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdfacet_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdFacet_H
+#define Patternist_XsdFacet_H
+
+#include "qitem_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdassertion_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD facet object.
+ *
+ * This class represents one of the following XML schema objects:
+ *
+ * <ul>
+ * <li><em>length</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-length">Definition</a></li>
+ * <li><em>minLength</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-minLength">Definition</a></li>
+ * <li><em>maxLength</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-maxLength">Definition</a></li>
+ * <li><em>pattern</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-pattern">Definition</a></li>
+ * <li><em>whiteSpace</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace">Definition</a></li>
+ * <li><em>maxInclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-maxInclusive">Definition</a></li>
+ * <li><em>maxExclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-maxExclusive">Definition</a></li>
+ * <li><em>minInclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-minInclusive">Definition</a></li>
+ * <li><em>minExclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-minExclusive">Definition</a></li>
+ * <li><em>totalDigits</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-totalDigits">Definition</a></li>
+ * <li><em>fractionDigits</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-fractionDigits">Definition</a></li>
+ * <li><em>enumeration</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-enumeration">Definition</a></li>
+ * <li><em>assertion</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-assertion">Definition</a></li>
+ * </ul>
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSFacet">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdFacet : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdFacet> Ptr;
+
+ /**
+ * Describes the type of the facet.
+ */
+ enum Type
+ {
+ None = 0, ///< An invalid facet.
+ Length = 1 << 0, ///< Match the exact length (<a href="http://www.w3.org/TR/xmlschema-2/#rf-length">Length Definition</a>)
+ MinimumLength = 1 << 1, ///< Match the minimum length (<a href="http://www.w3.org/TR/xmlschema-2/#rf-minLength">Minimum Length Definition</a>)
+ MaximumLength = 1 << 2, ///< Match the maximum length (<a href="http://www.w3.org/TR/xmlschema-2/#rf-maxLength">Maximum Length Definition</a>)
+ Pattern = 1 << 3, ///< Match a regular expression (<a href="http://www.w3.org/TR/xmlschema-2/#rf-pattern">Pattern Definition</a>)
+ WhiteSpace = 1 << 4, ///< Match a whitespace rule (<a href="http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace">White Space Definition</a>)
+ MaximumInclusive = 1 << 5, ///< Match a maximum inclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-maxInclusive">Maximum Inclusive Definition</a>)
+ MaximumExclusive = 1 << 6, ///< Match a maximum exclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-maxExclusive">Maximum Exclusive Definition</a>)
+ MinimumInclusive = 1 << 7, ///< Match a minimum inclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-minInclusive">Minimum Inclusive Definition</a>)
+ MinimumExclusive = 1 << 8, ///< Match a minimum exclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-minExclusive">Minimum Exclusive Definition</a>)
+ TotalDigits = 1 << 9, ///< Match some integer digits (<a href="http://www.w3.org/TR/xmlschema-2/#rf-totalDigits">Total Digits Definition</a>)
+ FractionDigits = 1 << 10, ///< Match some double digits (<a href="http://www.w3.org/TR/xmlschema-2/#rf-fractionDigits">Fraction Digits Definition</a>)
+ Enumeration = 1 << 11, ///< Match an enumeration (<a href="http://www.w3.org/TR/xmlschema-2/#rf-enumeration">Enumeration Definition</a>)
+ Assertion = 1 << 12, ///< Match an assertion (<a href="http://www.w3.org/TR/xmlschema-2/#rf-assertion">Assertion Definition</a>)
+ };
+ typedef QHash<XsdFacet::Type, XsdFacet::Ptr> Hash;
+ typedef QHashIterator<XsdFacet::Type, XsdFacet::Ptr> HashIterator;
+
+ /**
+ * Creates a new facet object of type None.
+ */
+ XsdFacet();
+
+ /**
+ * Sets the @p type of the facet.
+ *
+ * @see Type
+ */
+ void setType(Type type);
+
+ /**
+ * Returns the type of the facet.
+ */
+ Type type() const;
+
+ /**
+ * Sets the @p value of the facet.
+ *
+ * Depending on the type of the facet the
+ * value can be a string, interger, double etc.
+ *
+ * @note This method should be used for all types of facets
+ * except Pattern, Enumeration and Assertion.
+ */
+ void setValue(const AtomicValue::Ptr &value);
+
+ /**
+ * Returns the value of the facet or an empty pointer if facet
+ * type is Pattern, Enumeration or Assertion.
+ */
+ AtomicValue::Ptr value() const;
+
+ /**
+ * Sets the @p value of the facet.
+ *
+ * @note This method should be used for if the type of the
+ * facet is Pattern or Enumeration.
+ */
+ void setMultiValue(const AtomicValue::List &value);
+
+ /**
+ * Returns the value of the facet or an empty pointer if facet
+ * type is not of type Pattern or Enumeration.
+ */
+ AtomicValue::List multiValue() const;
+
+ /**
+ * Sets the @p assertions of the facet.
+ *
+ * @note This method should be used if the type of the
+ * facet is Assertion.
+ */
+ void setAssertions(const XsdAssertion::List &assertions);
+
+ /**
+ * Returns the assertions of the facet or an empty pointer if facet
+ * type is not of type Assertion.
+ */
+ XsdAssertion::List assertions() const;
+
+ /**
+ * Sets whether the facet is @p fixed.
+ *
+ * All facets except pattern, enumeration and assertion can be fixed.
+ */
+ void setFixed(bool fixed);
+
+ /**
+ * Returns whether the facet is fixed.
+ */
+ bool fixed() const;
+
+ /**
+ * Returns the textual description of the facet @p type.
+ */
+ static QString typeName(Type type);
+
+ private:
+ Type m_type;
+ AtomicValue::Ptr m_value;
+ AtomicValue::List m_multiValue;
+ XsdAssertion::List m_assertions;
+ bool m_fixed;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdidcache.cpp b/src/xmlpatterns/schema/qxsdidcache.cpp
new file mode 100644
index 0000000..cfca2e9
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidcache.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdidcache_p.h"
+
+#include <QtCore/QReadLocker>
+#include <QtCore/QWriteLocker>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdIdCache::addId(const QString &id)
+{
+ const QWriteLocker locker(&m_lock);
+ Q_ASSERT(!m_ids.contains(id));
+
+ m_ids.insert(id);
+}
+
+bool XsdIdCache::hasId(const QString &id) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_ids.contains(id);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdidcache_p.h b/src/xmlpatterns/schema/qxsdidcache_p.h
new file mode 100644
index 0000000..b24e4b7
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidcache_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdIdCache_H
+#define Patternist_XsdIdCache_H
+
+#include "qschemacomponent_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QReadWriteLock>
+#include <QtCore/QSet>
+#include <QtCore/QString>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Helper class for keeping track of all existing IDs in a schema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdIdCache : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdIdCache> Ptr;
+
+ /**
+ * Adds an @p id to the id cache.
+ */
+ void addId(const QString &id);
+
+ /**
+ * Returns whether the id cache contains the given @p id already.
+ */
+ bool hasId(const QString &id) const;
+
+ private:
+ QSet<QString> m_ids;
+ mutable QReadWriteLock m_lock;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdidchelper.cpp b/src/xmlpatterns/schema/qxsdidchelper.cpp
new file mode 100644
index 0000000..7740929
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidchelper.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdidchelper_p.h"
+
+#include "qderivedstring_p.h"
+#include "qxsdschemahelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+FieldNode::FieldNode()
+{
+}
+
+FieldNode::FieldNode(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type)
+ : m_item(item)
+ , m_data(data)
+ , m_type(type)
+{
+}
+
+bool FieldNode::isEmpty() const
+{
+ return m_item.isNull();
+}
+
+bool FieldNode::isEqualTo(const FieldNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
+{
+ if (m_type != other.m_type)
+ return false;
+
+ const DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(namePool, m_data);
+ const DerivedString<TypeString>::Ptr otherString = DerivedString<TypeString>::fromLexical(namePool, other.m_data);
+
+ return XsdSchemaHelper::constructAndCompare(string, AtomicComparator::OperatorEqual, otherString, m_type, context, reflection);
+}
+
+QXmlItem FieldNode::item() const
+{
+ return m_item;
+}
+
+TargetNode::TargetNode(const QXmlItem &item)
+ : m_item(item)
+{
+}
+
+QXmlItem TargetNode::item() const
+{
+ return m_item;
+}
+
+QVector<QXmlItem> TargetNode::fieldItems() const
+{
+ QVector<QXmlItem> items;
+
+ for (int i = 0; i < m_fields.count(); ++i)
+ items.append(m_fields.at(i).item());
+
+ return items;
+}
+
+int TargetNode::emptyFieldsCount() const
+{
+ int counter = 0;
+ for (int i = 0; i < m_fields.count(); ++i) {
+ if (m_fields.at(i).isEmpty())
+ ++counter;
+ }
+
+ return counter;
+}
+
+bool TargetNode::fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
+{
+ if (m_fields.count() != other.m_fields.count())
+ return false;
+
+ for (int i = 0; i < m_fields.count(); ++i) {
+ if (!m_fields.at(i).isEqualTo(other.m_fields.at(i), namePool, context, reflection))
+ return false;
+ }
+
+ return true;
+}
+
+void TargetNode::addField(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type)
+{
+ m_fields.append(FieldNode(item, data, type));
+}
+
+bool TargetNode::operator==(const TargetNode &other) const
+{
+ return (m_item.toNodeModelIndex() == other.m_item.toNodeModelIndex());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdidchelper_p.h b/src/xmlpatterns/schema/qxsdidchelper_p.h
new file mode 100644
index 0000000..f3a9bac
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidchelper_p.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdIdcHelper_H
+#define Patternist_XsdIdcHelper_H
+
+#include "qreportcontext_p.h"
+#include "qschematype_p.h"
+
+#include <QtXmlPatterns/QXmlItem>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short A helper class for validating identity constraints.
+ *
+ * This class represents a field node from the key-sequence as defined in
+ * the validation rules at http://www.w3.org/TR/xmlschema11-1/#d0e32243.
+ */
+ class FieldNode
+ {
+ public:
+ /**
+ * Creates an empty field node.
+ */
+ FieldNode();
+
+ /**
+ * Creates a field node that is bound to a xml node.
+ *
+ * @param item The xml node the field is bound to.
+ * @param data The string content of that field.
+ * @param type The type that is bound to that field.
+ */
+ FieldNode(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type);
+
+ /**
+ * Returns whether this field is empty.
+ *
+ * A field can be empty, if the xpath expression selects an absent attribute
+ * or element.
+ */
+ bool isEmpty() const;
+
+ /**
+ * Returns whether this field is equal to the @p other field.
+ *
+ * Equal means that both have the same type and there content is equal in the
+ * types value space.
+ */
+ bool isEqualTo(const FieldNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Returns the xml node item the field is bound to.
+ */
+ QXmlItem item() const;
+
+ private:
+ QXmlItem m_item;
+ QString m_data;
+ SchemaType::Ptr m_type;
+ };
+
+ /**
+ * @short A helper class for validating identity constraints.
+ *
+ * This class represents a target or qualified node from the target or qualified
+ * node set as defined in the validation rules at http://www.w3.org/TR/xmlschema11-1/#d0e32243.
+ *
+ * A target node is part of the qualified node set, if all of its fields are not empty.
+ */
+ class TargetNode
+ {
+ public:
+ /**
+ * Defines a set of target nodes.
+ */
+ typedef QSet<TargetNode> Set;
+
+ /**
+ * Creates a new target node that is bound to the xml node @p item.
+ */
+ explicit TargetNode(const QXmlItem &item);
+
+ /**
+ * Returns the xml node item the target node is bound to.
+ */
+ QXmlItem item() const;
+
+ /**
+ * Returns all xml node items, the fields of that target node are bound to.
+ */
+ QVector<QXmlItem> fieldItems() const;
+
+ /**
+ * Returns the number of fields that are empty.
+ */
+ int emptyFieldsCount() const;
+
+ /**
+ * Returns whether the target node has the same fields as the @p other target node.
+ */
+ bool fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Adds a new field to the target node with the given values.
+ */
+ void addField(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type);
+
+ /**
+ * Returns whether the target node is equal to the @p other target node.
+ */
+ bool operator==(const TargetNode &other) const;
+
+ private:
+ QXmlItem m_item;
+ QVector<FieldNode> m_fields;
+ };
+
+ /**
+ * Creates a hash value for the given target @p node.
+ */
+ inline uint qHash(const QPatternist::TargetNode &node)
+ {
+ return qHash(node.item().toNodeModelIndex());
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint.cpp b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp
new file mode 100644
index 0000000..12f8446
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdidentityconstraint_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdIdentityConstraint::setCategory(Category category)
+{
+ m_category = category;
+}
+
+XsdIdentityConstraint::Category XsdIdentityConstraint::category() const
+{
+ return m_category;
+}
+
+void XsdIdentityConstraint::setSelector(const XsdXPathExpression::Ptr &selector)
+{
+ m_selector = selector;
+}
+
+XsdXPathExpression::Ptr XsdIdentityConstraint::selector() const
+{
+ return m_selector;
+}
+
+void XsdIdentityConstraint::setFields(const XsdXPathExpression::List &fields)
+{
+ m_fields = fields;
+}
+
+void XsdIdentityConstraint::addField(const XsdXPathExpression::Ptr &field)
+{
+ m_fields.append(field);
+}
+
+XsdXPathExpression::List XsdIdentityConstraint::fields() const
+{
+ return m_fields;
+}
+
+void XsdIdentityConstraint::setReferencedKey(const XsdIdentityConstraint::Ptr &referencedKey)
+{
+ m_referencedKey = referencedKey;
+}
+
+XsdIdentityConstraint::Ptr XsdIdentityConstraint::referencedKey() const
+{
+ return m_referencedKey;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint_p.h b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h
new file mode 100644
index 0000000..a675ea0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdIdentityConstraint_H
+#define Patternist_XsdIdentityConstraint_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdxpathexpression_p.h"
+
+#include <QtCore/QStringList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD identity constraint object.
+ *
+ * This class represents the <em>identity constraint</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cIdentity-constraint_Definitions">here</a>.
+ *
+ * It contains information from either a <em>key</em> object, a <em>keyref</em> object or an
+ * <em>unique</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSIdentityConstraint">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdIdentityConstraint : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdIdentityConstraint> Ptr;
+ typedef QList<XsdIdentityConstraint::Ptr> List;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#icd-identity-constraint_category">category</a> of the identity constraint.
+ */
+ enum Category
+ {
+ Key = 1, ///< The constraint is a key constraint
+ KeyReference, ///< The constraint is a keyref constraint
+ Unique ///< The constraint is an unique constraint
+ };
+
+ /**
+ * Sets the @p category of the identity constraint.
+ *
+ * @see Category
+ */
+ void setCategory(Category category);
+
+ /**
+ * Returns the category of the identity constraint.
+ */
+ Category category() const;
+
+ /**
+ * Sets the @p selector of the identity constraint.
+ *
+ * The selector is a restricted XPath 1.0 expression,
+ * that selects a set of nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#icd-selector"></a>
+ */
+ void setSelector(const XsdXPathExpression::Ptr &selector);
+
+ /**
+ * Returns the selector of the identity constraint.
+ */
+ XsdXPathExpression::Ptr selector() const;
+
+ /**
+ * Sets the @p fields of the identity constraint.
+ *
+ * Each field is a restricted XPath 1.0 expression,
+ * that selects a set of nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#icd-fields"></a>
+ */
+ void setFields(const XsdXPathExpression::List &fields);
+
+ /**
+ * Adds a new @p field to the identity constraint.
+ */
+ void addField(const XsdXPathExpression::Ptr &field);
+
+ /**
+ * Returns all fields of the identity constraint.
+ */
+ XsdXPathExpression::List fields() const;
+
+ /**
+ * Sets the referenced @p key of the identity constraint.
+ *
+ * The key points to a identity constraint of type Key or Unique.
+ *
+ * The identity constraint has only a referenced key if its
+ * type is KeyReference.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#icd-referenced_key"></a>
+ */
+ void setReferencedKey(const XsdIdentityConstraint::Ptr &key);
+
+ /**
+ * Returns the referenced key of the identity constraint or an empty
+ * pointer if its type is not KeyReference.
+ */
+ XsdIdentityConstraint::Ptr referencedKey() const;
+
+ private:
+ Category m_category;
+ XsdXPathExpression::Ptr m_selector;
+ XsdXPathExpression::List m_fields;
+ XsdIdentityConstraint::Ptr m_referencedKey;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdinstancereader.cpp b/src/xmlpatterns/schema/qxsdinstancereader.cpp
new file mode 100644
index 0000000..a7cb735
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdinstancereader.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdinstancereader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdInstanceReader::XsdInstanceReader(const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context)
+ : m_context(context)
+ , m_model(model->iterate(model->root(QXmlNodeModelIndex()), QXmlNodeModelIndex::AxisChild))
+{
+}
+
+bool XsdInstanceReader::atEnd() const
+{
+ return (m_model.current() == AbstractXmlPullProvider::EndOfInput);
+}
+
+void XsdInstanceReader::readNext()
+{
+ m_model.next();
+
+ if (m_model.current() == AbstractXmlPullProvider::StartElement) {
+ m_cachedAttributes = m_model.attributes();
+ m_cachedAttributeItems = m_model.attributeItems();
+ m_cachedSourceLocation = m_model.sourceLocation();
+ m_cachedItem = QXmlItem(m_model.index());
+ }
+}
+
+bool XsdInstanceReader::isStartElement() const
+{
+ return (m_model.current() == AbstractXmlPullProvider::StartElement);
+}
+
+bool XsdInstanceReader::isEndElement() const
+{
+ return (m_model.current() == AbstractXmlPullProvider::EndElement);
+}
+
+bool XsdInstanceReader::hasChildText() const
+{
+ const QXmlNodeModelIndex index = m_model.index();
+ QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild);
+
+ QXmlNodeModelIndex currentIndex = it->next();
+ while (!currentIndex.isNull()) {
+ if (currentIndex.kind() == QXmlNodeModelIndex::Text)
+ return true;
+
+ currentIndex = it->next();
+ }
+
+ return false;
+}
+
+bool XsdInstanceReader::hasChildElement() const
+{
+ const QXmlNodeModelIndex index = m_model.index();
+ QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild);
+
+ QXmlNodeModelIndex currentIndex = it->next();
+ while (!currentIndex.isNull()) {
+ if (currentIndex.kind() == QXmlNodeModelIndex::Element)
+ return true;
+
+ currentIndex = it->next();
+ }
+
+ return false;
+}
+
+QXmlName XsdInstanceReader::name() const
+{
+ return m_model.name();
+}
+
+QXmlName XsdInstanceReader::convertToQName(const QString &name) const
+{
+ const int pos = name.indexOf(QLatin1Char(':'));
+
+ QXmlName::PrefixCode prefixCode = 0;
+ QXmlName::NamespaceCode namespaceCode;
+ QXmlName::LocalNameCode localNameCode;
+ if (pos != -1) {
+ prefixCode = m_context->namePool()->allocatePrefix(name.left(pos));
+ namespaceCode = m_cachedItem.toNodeModelIndex().namespaceForPrefix(prefixCode);
+ localNameCode = m_context->namePool()->allocateLocalName(name.mid(pos + 1));
+ } else {
+ prefixCode = StandardPrefixes::empty;
+ namespaceCode = m_cachedItem.toNodeModelIndex().namespaceForPrefix(prefixCode);
+ if (namespaceCode == -1)
+ namespaceCode = StandardNamespaces::empty;
+ localNameCode = m_context->namePool()->allocateLocalName(name);
+ }
+
+ return QXmlName(namespaceCode, localNameCode, prefixCode);
+}
+
+bool XsdInstanceReader::hasAttribute(const QXmlName &name) const
+{
+ return m_cachedAttributes.contains(name);
+}
+
+QString XsdInstanceReader::attribute(const QXmlName &name) const
+{
+ Q_ASSERT(m_cachedAttributes.contains(name));
+
+ return m_cachedAttributes.value(name);
+}
+
+QSet<QXmlName> XsdInstanceReader::attributeNames() const
+{
+ return m_cachedAttributes.keys().toSet();
+}
+
+QString XsdInstanceReader::text() const
+{
+ const QXmlNodeModelIndex index = m_model.index();
+ QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild);
+
+ QString result;
+
+ QXmlNodeModelIndex currentIndex = it->next();
+ while (!currentIndex.isNull()) {
+ if (currentIndex.kind() == QXmlNodeModelIndex::Text) {
+ result.append(Item(currentIndex).stringValue());
+ }
+
+ currentIndex = it->next();
+ }
+
+ return result;
+}
+
+QXmlItem XsdInstanceReader::item() const
+{
+ return m_cachedItem;
+}
+
+QXmlItem XsdInstanceReader::attributeItem(const QXmlName &name) const
+{
+ return m_cachedAttributeItems.value(name);
+}
+
+QSourceLocation XsdInstanceReader::sourceLocation() const
+{
+ return m_cachedSourceLocation;
+}
+
+QVector<QXmlName> XsdInstanceReader::namespaceBindings(const QXmlNodeModelIndex &index) const
+{
+ return index.namespaceBindings();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdinstancereader_p.h b/src/xmlpatterns/schema/qxsdinstancereader_p.h
new file mode 100644
index 0000000..9c9fcd1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdinstancereader_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdInstanceReader_H
+#define Patternist_XsdInstanceReader_H
+
+#include "qabstractxmlnodemodel.h"
+#include "qpullbridge_p.h"
+#include "qxsdschemacontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short The schema instance reader.
+ *
+ * This class reads in a xml instance document from a QAbstractXmlNodeModel
+ * and provides a QXmlStreamReader like interface with some additional context
+ * information.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdInstanceReader
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdInstanceReader> Ptr;
+
+ /**
+ * Creates a new instance reader that will read the data from
+ * the given @p model.
+ *
+ * @param model The model the data are read from.
+ * @param context The context that is used for error reporting etc.
+ */
+ XsdInstanceReader(const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context);
+
+ protected:
+ /**
+ * Returns @c true if the end of the document is reached, @c false otherwise.
+ */
+ bool atEnd() const;
+
+ /**
+ * Reads the next node from the document.
+ */
+ void readNext();
+
+ /**
+ * Returns whether the current node is a start element.
+ */
+ bool isStartElement() const;
+
+ /**
+ * Returns whether the current node is an end element.
+ */
+ bool isEndElement() const;
+
+ /**
+ * Returns whether the current node has a text node among its children.
+ */
+ bool hasChildText() const;
+
+ /**
+ * Returns whether the current node has an element node among its children.
+ */
+ bool hasChildElement() const;
+
+ /**
+ * Returns the name of the current node.
+ */
+ QXmlName name() const;
+
+ /**
+ * Returns whether the current node has an attribute with the given @p name.
+ */
+ bool hasAttribute(const QXmlName &name) const;
+
+ /**
+ * Returns the attribute with the given @p name of the current node.
+ */
+ QString attribute(const QXmlName &name) const;
+
+ /**
+ * Returns the list of attribute names of the current node.
+ */
+ QSet<QXmlName> attributeNames() const;
+
+ /**
+ * Returns the concatenated text of all direct child text nodes.
+ */
+ QString text() const;
+
+ /**
+ * Converts a qualified name into a QXmlName according to the namespace
+ * mappings of the current node.
+ */
+ QXmlName convertToQName(const QString &name) const;
+
+ /**
+ * Returns a source location object for the current position.
+ */
+ QSourceLocation sourceLocation() const;
+
+ /**
+ * Returns the QXmlItem for the current position.
+ */
+ QXmlItem item() const;
+
+ /**
+ * Returns the QXmlItem for the attribute with the given @p name at the current position.
+ */
+ QXmlItem attributeItem(const QXmlName &name) const;
+
+ /**
+ * Returns the namespace bindings for the given node model @p index.
+ */
+ QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * The shared schema context.
+ */
+ XsdSchemaContext::Ptr m_context;
+
+ private:
+ PullBridge m_model;
+ QHash<QXmlName, QString> m_cachedAttributes;
+ QHash<QXmlName, QXmlItem> m_cachedAttributeItems;
+ QSourceLocation m_cachedSourceLocation;
+ QXmlItem m_cachedItem;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdmodelgroup.cpp b/src/xmlpatterns/schema/qxsdmodelgroup.cpp
new file mode 100644
index 0000000..69e5fad
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdmodelgroup.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdmodelgroup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdModelGroup::XsdModelGroup()
+ : m_compositor(SequenceCompositor)
+{
+}
+
+bool XsdModelGroup::isModelGroup() const
+{
+ return true;
+}
+
+void XsdModelGroup::setCompositor(ModelCompositor compositor)
+{
+ m_compositor = compositor;
+}
+
+XsdModelGroup::ModelCompositor XsdModelGroup::compositor() const
+{
+ return m_compositor;
+}
+
+void XsdModelGroup::setParticles(const XsdParticle::List &particles)
+{
+ m_particles = particles;
+}
+
+XsdParticle::List XsdModelGroup::particles() const
+{
+ return m_particles;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdmodelgroup_p.h b/src/xmlpatterns/schema/qxsdmodelgroup_p.h
new file mode 100644
index 0000000..c4f54e5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdmodelgroup_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdModelGroup_H
+#define Patternist_XsdModelGroup_H
+
+#include "qxsdparticle_p.h"
+#include "qxsdterm_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename N> class QList;
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD model group object.
+ *
+ * This class represents the <em>model group</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cModel_Group_Definitions">here</a>.
+ *
+ * It contains information from either a <em>sequence</em> object, a <em>choice</em> object or an
+ * <em>all</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSModelGroup">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdModelGroup : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdModelGroup> Ptr;
+ typedef QList<XsdModelGroup::Ptr> List;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#mg-compositor">compositor</a> of the model group.
+ */
+ enum ModelCompositor
+ {
+ SequenceCompositor, ///< The model group is a sequence.
+ ChoiceCompositor, ///< The model group is a choice.
+ AllCompositor ///< The model group contains elements only.
+ };
+
+ /**
+ * Creates a new model group object.
+ */
+ XsdModelGroup();
+
+ /**
+ * Returns always @c true, used to avoid dynamic casts.
+ */
+ virtual bool isModelGroup() const;
+
+ /**
+ * Sets the @p compositor of the model group.
+ *
+ * @see ModelCompositor
+ */
+ void setCompositor(ModelCompositor compositor);
+
+ /**
+ * Returns the compositor of the model group.
+ */
+ ModelCompositor compositor() const;
+
+ /**
+ * Sets the list of @p particles of the model group.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#mg-particles">Particles Definition</a>
+ */
+ void setParticles(const XsdParticle::List &particles);
+
+ /**
+ * Returns the list of particles of the model group.
+ */
+ XsdParticle::List particles() const;
+
+ private:
+ ModelCompositor m_compositor;
+ XsdParticle::List m_particles;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdnotation.cpp b/src/xmlpatterns/schema/qxsdnotation.cpp
new file mode 100644
index 0000000..2cd27a4
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdnotation.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdnotation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdNotation::setPublicId(const DerivedString<TypeToken>::Ptr &id)
+{
+ m_publicId = id;
+}
+
+DerivedString<TypeToken>::Ptr XsdNotation::publicId() const
+{
+ return m_publicId;
+}
+
+void XsdNotation::setSystemId(const AnyURI::Ptr &id)
+{
+ m_systemId = id;
+}
+
+AnyURI::Ptr XsdNotation::systemId() const
+{
+ return m_systemId;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdnotation_p.h b/src/xmlpatterns/schema/qxsdnotation_p.h
new file mode 100644
index 0000000..598392a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdnotation_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdNotation_H
+#define Patternist_XsdNotation_H
+
+#include "qanyuri_p.h"
+#include "qderivedstring_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD notation object, which should not
+ * be confused with the atomic type @c xs:NOTATION.
+ *
+ * This class represents the <em>notation</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cNotation_Declarations">here</a>.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#XS-NotationDecl">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdNotation : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdNotation> Ptr;
+ typedef QList<XsdNotation::Ptr> List;
+
+ /**
+ * Sets the public @p identifier of the notation.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nd-public_identifier">Public Identifier Definition</a>
+ */
+ void setPublicId(const DerivedString<TypeToken>::Ptr &identifier);
+
+ /**
+ * Returns the public identifier of the notation.
+ */
+ DerivedString<TypeToken>::Ptr publicId() const;
+
+ /**
+ * Sets the system @p identifier of the notation.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nd-system_identifier">System Identifier Definition</a>
+ */
+ void setSystemId(const AnyURI::Ptr &identifier);
+
+ /**
+ * Returns the system identifier of the notation.
+ */
+ AnyURI::Ptr systemId() const;
+
+ private:
+ DerivedString<TypeToken>::Ptr m_publicId;
+ AnyURI::Ptr m_systemId;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdparticle.cpp b/src/xmlpatterns/schema/qxsdparticle.cpp
new file mode 100644
index 0000000..650524c
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticle.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdparticle_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdParticle::XsdParticle()
+ : m_minimumOccurs(1)
+ , m_maximumOccurs(1)
+ , m_maximumOccursUnbounded(false)
+{
+}
+
+void XsdParticle::setMinimumOccurs(unsigned int occurs)
+{
+ m_minimumOccurs = occurs;
+}
+
+unsigned int XsdParticle::minimumOccurs() const
+{
+ return m_minimumOccurs;
+}
+
+void XsdParticle::setMaximumOccurs(unsigned int occurs)
+{
+ m_maximumOccurs = occurs;
+}
+
+unsigned int XsdParticle::maximumOccurs() const
+{
+ return m_maximumOccurs;
+}
+
+void XsdParticle::setMaximumOccursUnbounded(bool unbounded)
+{
+ m_maximumOccursUnbounded = unbounded;
+}
+
+bool XsdParticle::maximumOccursUnbounded() const
+{
+ return m_maximumOccursUnbounded;
+}
+
+void XsdParticle::setTerm(const XsdTerm::Ptr &term)
+{
+ m_term = term;
+}
+
+XsdTerm::Ptr XsdParticle::term() const
+{
+ return m_term;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdparticle_p.h b/src/xmlpatterns/schema/qxsdparticle_p.h
new file mode 100644
index 0000000..4e6561e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticle_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdParticle_H
+#define Patternist_XsdParticle_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdterm_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD particle object.
+ *
+ * This class represents the <em>particle</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cParticles">here</a>.
+ *
+ * It contains information about the number of occurrence and a reference to
+ * either an <em>element</em> object, a <em>group</em> object or an <em>any</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSParticle">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdParticle : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdParticle> Ptr;
+ typedef QList<XsdParticle::Ptr> List;
+
+ /**
+ * Creates a new particle object.
+ */
+ XsdParticle();
+
+ /**
+ * Sets the minimum @p occurrence of the particle.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-min_occurs">Minimum Occurrence Definition</a>
+ */
+ void setMinimumOccurs(unsigned int occurrence);
+
+ /**
+ * Returns the minimum occurrence of the particle.
+ */
+ unsigned int minimumOccurs() const;
+
+ /**
+ * Sets the maximum @p occurrence of the particle.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-max_occurs">Maximum Occurrence Definition</a>
+ */
+ void setMaximumOccurs(unsigned int occurrence);
+
+ /**
+ * Returns the maximum occurrence of the particle.
+ *
+ * @note This value has only a meaning if maximumOccursUnbounded is @c false.
+ */
+ unsigned int maximumOccurs() const;
+
+ /**
+ * Sets whether the maximum occurrence of the particle is unbounded.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-max_occurs">Maximum Occurrence Definition</a>
+ */
+ void setMaximumOccursUnbounded(bool unbounded);
+
+ /**
+ * Returns whether the maximum occurrence of the particle is unbounded.
+ */
+ bool maximumOccursUnbounded() const;
+
+ /**
+ * Sets the @p term of the particle.
+ *
+ * The term can be an element, a model group or an element wildcard.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-term">Term Definition</a>
+ */
+ void setTerm(const XsdTerm::Ptr &term);
+
+ /**
+ * Returns the term of the particle.
+ */
+ XsdTerm::Ptr term() const;
+
+ private:
+ unsigned int m_minimumOccurs;
+ unsigned int m_maximumOccurs;
+ bool m_maximumOccursUnbounded;
+ XsdTerm::Ptr m_term;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp
new file mode 100644
index 0000000..15c2afe
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp
@@ -0,0 +1,570 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdparticlechecker_p.h"
+
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdstatemachinebuilder_p.h"
+#include "qxsdtypechecker_p.h"
+
+#include <QtCore/QFile>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ /**
+ * This template specialization is picked up by XsdStateMachine and allows us
+ * to print nice edge labels.
+ */
+ template <>
+ QString XsdStateMachine<XsdTerm::Ptr>::transitionTypeToString(XsdTerm::Ptr term) const
+ {
+ if (!term)
+ return QLatin1String("(empty)");
+
+ if (term->isElement()) {
+ return XsdElement::Ptr(term)->displayName(m_namePool);
+ } else if (term->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(term);
+ return QLatin1String("(wildcard)");
+ } else {
+ return QString();
+ }
+ }
+}
+
+/**
+ * This method is used by the isUPAConform method to check whether @p term and @p otherTerm
+ * are the same resp. match each other.
+ */
+static bool termMatches(const XsdTerm::Ptr &term, const XsdTerm::Ptr &otherTerm, const NamePool::Ptr &namePool)
+{
+ if (term->isElement()) {
+ const XsdElement::Ptr element(term);
+
+ if (otherTerm->isElement()) {
+ // both, the term and the other term are elements
+
+ const XsdElement::Ptr otherElement(otherTerm);
+
+ // if they have the same name they match
+ if (element->name(namePool) == otherElement->name(namePool))
+ return true;
+
+ } else if (otherTerm->isWildcard()) {
+ // the term is an element and the other term a wildcard
+
+ const XsdWildcard::Ptr wildcard(otherTerm);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name = element->name(namePool);
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ // if the wildcards namespace constraint allows the elements name, they match
+ if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool))
+ return true;
+ }
+ } else if (term->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(term);
+
+ if (otherTerm->isElement()) {
+ // the term is a wildcard and the other term an element
+
+ const XsdElement::Ptr otherElement(otherTerm);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name = otherElement->name(namePool);
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ // if the wildcards namespace constraint allows the elements name, they match
+ if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool))
+ return true;
+
+ } else if (otherTerm->isWildcard()) {
+ // both, the term and the other term are wildcards
+
+ const XsdWildcard::Ptr otherWildcard(otherTerm);
+
+ // check if the range of the wildcard overlaps.
+ const XsdWildcard::Ptr intersectionWildcard = XsdSchemaHelper::wildcardIntersection(wildcard, otherWildcard);
+ if (!intersectionWildcard ||
+ (intersectionWildcard && !(intersectionWildcard->namespaceConstraint()->variety() != XsdWildcard::NamespaceConstraint::Not && intersectionWildcard->namespaceConstraint()->namespaces().isEmpty())))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * This method is used by the subsumes algorithm to check whether the @p derivedTerm is validly derived from the @p baseTerm.
+ *
+ * @param baseTerm The term of the base component (type or group).
+ * @param derivedTerm The term of the derived component (type or group).
+ * @param particles A hash to map the passed base and derived term to the particles they belong to.
+ * @param context The schema context.
+ * @param errorMsg The error message in the case that an error occurs.
+ */
+static bool derivedTermValid(const XsdTerm::Ptr &baseTerm, const XsdTerm::Ptr &derivedTerm, const QHash<XsdTerm::Ptr, XsdParticle::Ptr> &particles, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ const NamePool::Ptr namePool(context->namePool());
+
+ // find the particles where the base and derived term belongs to
+ const XsdParticle::Ptr baseParticle = particles.value(baseTerm);
+ const XsdParticle::Ptr derivedParticle = particles.value(derivedTerm);
+
+ // check that an empty particle can not be derived from a non-empty particle
+ if (derivedParticle && baseParticle) {
+ if (XsdSchemaHelper::isParticleEmptiable(derivedParticle) && !XsdSchemaHelper::isParticleEmptiable(baseParticle)) {
+ errorMsg = QtXmlPatterns::tr("Empty particle cannot be derived from non-empty particle.");
+ return false;
+ }
+ }
+
+ if (baseTerm->isElement()) {
+ const XsdElement::Ptr element(baseTerm);
+
+ if (derivedTerm->isElement()) {
+ // if both terms are elements
+
+ const XsdElement::Ptr derivedElement(derivedTerm);
+
+ // check names are equal
+ if (element->name(namePool) != derivedElement->name(namePool)) {
+ errorMsg = QtXmlPatterns::tr("Derived particle is missing element %1.").arg(formatKeyword(element->displayName(namePool)));
+ return false;
+ }
+
+ // check value constraints are equal (if available)
+ if (element->valueConstraint() && element->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ if (!derivedElement->valueConstraint()) {
+ errorMsg = QtXmlPatterns::tr("Derived element %1 is missing value constraint as defined in base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ if (derivedElement->valueConstraint()->variety() != XsdElement::ValueConstraint::Fixed) {
+ errorMsg = QtXmlPatterns::tr("Derived element %1 has weaker value constraint than base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ const QSourceLocation dummyLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1);
+ const XsdTypeChecker checker(context, QVector<QXmlName>(), dummyLocation);
+ if (!checker.valuesAreEqual(element->valueConstraint()->value(), derivedElement->valueConstraint()->value(), derivedElement->type())) {
+ errorMsg = QtXmlPatterns::tr("Fixed value constraint of element %1 differs from value constraint in base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+ }
+
+ // check that a derived element can not be nillable if the base element is not nillable
+ if (!element->isNillable() && derivedElement->isNillable()) {
+ errorMsg = QtXmlPatterns::tr("Derived element %1 cannot be nillable as base element is not nillable.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ // check that the constraints of the derived element are more strict then the constraints of the base element
+ const XsdElement::BlockingConstraints baseConstraints = element->disallowedSubstitutions();
+ const XsdElement::BlockingConstraints derivedConstraints = derivedElement->disallowedSubstitutions();
+ if (((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint)) ||
+ ((baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint)) ||
+ ((baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint))) {
+ errorMsg = QtXmlPatterns::tr("Block constraints of derived element %1 must not be more weaker than in the base element.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ // if the type of both elements is the same we can stop testing here
+ if (element->type()->name(namePool) == derivedElement->type()->name(namePool))
+ return true;
+
+ // check that the type of the derived element can validly derived from the type of the base element
+ if (derivedElement->type()->isSimpleType()) {
+ if (!XsdSchemaHelper::isSimpleDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) {
+ errorMsg = QtXmlPatterns::tr("Simple type of derived element %1 cannot be validly derived from base element.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+ } else if (derivedElement->type()->isComplexType()) {
+ if (!XsdSchemaHelper::isComplexDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) {
+ errorMsg = QtXmlPatterns::tr("Complex type of derived element %1 cannot be validly derived from base element.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+ }
+
+ // if both, derived and base element, have a complex type that contains a particle itself, apply the subsumes algorithm
+ // recursive on their particles
+ if (element->type()->isComplexType() && derivedElement->type()->isComplexType()) {
+ if (element->type()->isDefinedBySchema() && derivedElement->type()->isDefinedBySchema()) {
+ const XsdComplexType::Ptr baseType(element->type());
+ const XsdComplexType::Ptr derivedType(derivedElement->type());
+ if ((baseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ baseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) &&
+ (derivedType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ derivedType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
+
+ return XsdParticleChecker::subsumes(baseType->contentType()->particle(), derivedType->contentType()->particle(), context, errorMsg);
+ }
+ }
+ }
+
+ return true;
+ } else if (derivedTerm->isWildcard()) {
+ // derive a wildcard from an element is not allowed
+ errorMsg = QtXmlPatterns::tr("Element %1 is missing in derived particle.").arg(formatKeyword(element->displayName(namePool)));
+ return false;
+ }
+ } else if (baseTerm->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(baseTerm);
+
+ if (derivedTerm->isElement()) {
+ // the base term is a wildcard and derived term an element
+
+ const XsdElement::Ptr derivedElement(derivedTerm);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name = derivedElement->name(namePool);
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ // check that name of the element is allowed by the wildcards namespace constraint
+ if (!XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) {
+ errorMsg = QtXmlPatterns::tr("Element %1 does not match namespace constraint of wildcard in base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ } else if (derivedTerm->isWildcard()) {
+ // both, derived and base term are wildcards
+
+ const XsdWildcard::Ptr derivedWildcard(derivedTerm);
+
+ // check that the derived wildcard is a valid subset of the base wildcard
+ if (!XsdSchemaHelper::isWildcardSubset(derivedWildcard, wildcard)) {
+ errorMsg = QtXmlPatterns::tr("Wildcard in derived particle is not a valid subset of wildcard in base particle.");
+ return false;
+ }
+
+ if (!XsdSchemaHelper::checkWildcardProcessContents(wildcard, derivedWildcard)) {
+ errorMsg = QtXmlPatterns::tr("processContent of wildcard in derived particle is weaker than wildcard in base particle.");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+typedef QHash<QXmlName, XsdElement::Ptr> ElementHash;
+
+/**
+ * Internal helper method that checks if the given @p particle contains an element with the
+ * same name and type twice.
+ */
+static bool hasDuplicatedElementsInternal(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, ElementHash &hash, XsdElement::Ptr &conflictingElement)
+{
+ const XsdTerm::Ptr term = particle->term();
+ if (term->isElement()) {
+ const XsdElement::Ptr mainElement(term);
+ XsdElement::List substGroups = mainElement->substitutionGroups();
+ if (substGroups.isEmpty())
+ substGroups << mainElement;
+
+ for (int i = 0; i < substGroups.count(); ++i) {
+ const XsdElement::Ptr element = substGroups.at(i);
+ if (hash.contains(element->name(namePool))) {
+ if (element->type()->name(namePool) != hash.value(element->name(namePool))->type()->name(namePool)) {
+ conflictingElement = element;
+ return true;
+ }
+ } else {
+ hash.insert(element->name(namePool), element);
+ }
+ }
+ } else if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group(term);
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ if (hasDuplicatedElementsInternal(particles.at(i), namePool, hash, conflictingElement))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool XsdParticleChecker::hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement)
+{
+ ElementHash hash;
+ return hasDuplicatedElementsInternal(particle, namePool, hash, conflictingElement);
+}
+
+bool XsdParticleChecker::isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool)
+{
+
+ /**
+ * In case we encounter an <xsd:all> element, don't construct a state machine, but use the approach
+ * described at http://www.w3.org/TR/xmlschema-1/#non-ambig
+ * Reason: For n elements inside the <xsd:all>, represented in the NDA, the state machine
+ * constructs n! states in the DFA, which does not scale.
+ */
+ if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ if (group->compositor() == XsdModelGroup::AllCompositor)
+ return isUPAConformXsdAll(particle, namePool);
+ }
+
+ /**
+ * The algorithm is implemented like described in http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.2
+ */
+
+ // create a state machine for the given particle
+ XsdStateMachine<XsdTerm::Ptr> stateMachine(namePool);
+
+ XsdStateMachineBuilder builder(&stateMachine, namePool);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(particle, endState);
+ builder.addStartState(startState);
+
+/*
+ static int counter = 0;
+ {
+ QFile file(QString("/tmp/file_upa%1.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ stateMachine.outputGraph(&file, "Base");
+ file.close();
+ }
+ ::system(QString("dot -Tpng /tmp/file_upa%1.dot -o/tmp/file_upa%1.png").arg(counter).toLatin1().data());
+*/
+ const XsdStateMachine<XsdTerm::Ptr> dfa = stateMachine.toDFA();
+/*
+ {
+ QFile file(QString("/tmp/file_upa%1dfa.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ dfa.outputGraph(&file, "Base");
+ file.close();
+ }
+ ::system(QString("dot -Tpng /tmp/file_upa%1dfa.dot -o/tmp/file_upa%1dfa.png").arg(counter).toLatin1().data());
+*/
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> states = dfa.states();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > > transitions = dfa.transitions();
+
+ // the basic idea of that algorithm is to iterate over all states of that machine and check that no two edges
+ // that match on the same term leave a state, so for a given term it should always be obvious which edge to take
+ QHashIterator<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> stateIt(states);
+ while (stateIt.hasNext()) { // iterate over all states
+ stateIt.next();
+
+ // fetch all transitions the current state allows
+ const QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > currentTransitions = transitions.value(stateIt.key());
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > transitionIt(currentTransitions);
+ while (transitionIt.hasNext()) { // iterate over all transitions
+ transitionIt.next();
+
+ if (transitionIt.value().size() > 1) {
+ // we have one state with two edges leaving it, that means
+ // the XsdTerm::Ptr exists twice, that is an error
+ return false;
+ }
+
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > innerTransitionIt(currentTransitions);
+ while (innerTransitionIt.hasNext()) { // iterate over all transitions again, as we have to compare all transitions with all
+ innerTransitionIt.next();
+
+ if (transitionIt.key() == innerTransitionIt.key()) // do no compare with ourself
+ continue;
+
+ // use the helper method termMatches to check if both term matches
+ if (termMatches(transitionIt.key(), innerTransitionIt.key(), namePool))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool XsdParticleChecker::isUPAConformXsdAll(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool)
+{
+ /**
+ * see http://www.w3.org/TR/xmlschema-1/#non-ambig
+ */
+ const XsdModelGroup::Ptr group(particle->term());
+ const XsdParticle::List particles = group->particles();
+ const int count = particles.count();
+ for (int left = 0; left < count; ++left) {
+ for (int right = left+1; right < count; ++right) {
+ if (termMatches(particles.at(left)->term(), particles.at(right)->term(), namePool))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool XsdParticleChecker::subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ /**
+ * The algorithm is implemented like described in http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.3
+ */
+
+ const NamePool::Ptr namePool(context->namePool());
+
+ XsdStateMachine<XsdTerm::Ptr> baseStateMachine(namePool);
+ XsdStateMachine<XsdTerm::Ptr> derivedStateMachine(namePool);
+
+ // build up state machines for both particles
+ {
+ XsdStateMachineBuilder builder(&baseStateMachine, namePool);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(particle, endState);
+ builder.addStartState(startState);
+
+ baseStateMachine = baseStateMachine.toDFA();
+ }
+ {
+ XsdStateMachineBuilder builder(&derivedStateMachine, namePool);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(derivedParticle, endState);
+ builder.addStartState(startState);
+
+ derivedStateMachine = derivedStateMachine.toDFA();
+ }
+
+ QHash<XsdTerm::Ptr, XsdParticle::Ptr> particlesHash = XsdStateMachineBuilder::particleLookupMap(particle);
+ particlesHash.unite(XsdStateMachineBuilder::particleLookupMap(derivedParticle));
+
+/*
+ static int counter = 0;
+ {
+ QFile file(QString("/tmp/file_base%1.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ baseStateMachine.outputGraph(&file, QLatin1String("Base"));
+ file.close();
+ }
+ {
+ QFile file(QString("/tmp/file_derived%1.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ derivedStateMachine.outputGraph(&file, QLatin1String("Base"));
+ file.close();
+ }
+ ::system(QString("dot -Tpng /tmp/file_base%1.dot -o/tmp/file_base%1.png").arg(counter).toLatin1().data());
+ ::system(QString("dot -Tpng /tmp/file_derived%1.dot -o/tmp/file_derived%1.png").arg(counter).toLatin1().data());
+*/
+
+ const XsdStateMachine<XsdTerm::Ptr>::StateId baseStartState = baseStateMachine.startState();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> baseStates = baseStateMachine.states();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > > baseTransitions = baseStateMachine.transitions();
+
+ const XsdStateMachine<XsdTerm::Ptr>::StateId derivedStartState = derivedStateMachine.startState();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> derivedStates = derivedStateMachine.states();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > > derivedTransitions = derivedStateMachine.transitions();
+
+ // @see http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.3.1
+
+ // define working set
+ QList<QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> > workSet;
+ QList<QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> > processedSet;
+
+ // 1) fill working set initially with start states
+ workSet.append(qMakePair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId>(baseStartState, derivedStartState));
+ processedSet.append(qMakePair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId>(baseStartState, derivedStartState));
+
+ while (!workSet.isEmpty()) { // while there are state sets to process
+
+ // 3) dequeue on state set
+ const QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> set = workSet.takeFirst();
+
+ const QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > derivedTrans = derivedTransitions.value(set.second);
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > derivedIt(derivedTrans);
+
+ const QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > baseTrans = baseTransitions.value(set.first);
+
+ while (derivedIt.hasNext()) {
+ derivedIt.next();
+
+ bool found = false;
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > baseIt(baseTrans);
+ while (baseIt.hasNext()) {
+ baseIt.next();
+ if (derivedTermValid(baseIt.key(), derivedIt.key(), particlesHash, context, errorMsg)) {
+ const QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> endSet =
+ qMakePair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId>(baseIt.value().first(), derivedIt.value().first());
+ if (!processedSet.contains(endSet) && !workSet.contains(endSet)) {
+ workSet.append(endSet);
+ processedSet.append(endSet);
+ }
+
+ found = true;
+ }
+ }
+
+ if (!found) {
+ return false;
+ }
+ }
+ }
+
+ // 5)
+ QHashIterator<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> it(derivedStates);
+ while (it.hasNext()) {
+ it.next();
+
+ if (it.value() == XsdStateMachine<XsdTerm::Ptr>::EndState || it.value() == XsdStateMachine<XsdTerm::Ptr>::StartEndState) {
+ for (int i = 0; i < processedSet.count(); ++i) {
+ if (processedSet.at(i).second == it.key() &&
+ (baseStates.value(processedSet.at(i).first) != XsdStateMachine<XsdTerm::Ptr>::EndState &&
+ baseStates.value(processedSet.at(i).first) != XsdStateMachine<XsdTerm::Ptr>::StartEndState)) {
+ errorMsg = QtXmlPatterns::tr("Derived particle allows content that is not allowed in the base particle.");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdparticlechecker_p.h b/src/xmlpatterns/schema/qxsdparticlechecker_p.h
new file mode 100644
index 0000000..40c525a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticlechecker_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdParticleChecker_H
+#define Patternist_XsdParticleChecker_H
+
+#include "qxsdelement_p.h"
+#include "qxsdparticle_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdwildcard_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class to check validity of particles.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdParticleChecker
+ {
+ public:
+ /**
+ * Checks whether the given @p particle has two or more element
+ * declarations with the same name but different type definitions.
+ */
+ static bool hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement);
+
+ /**
+ * Checks whether the given @p particle is valid according the
+ * UPA (http://www.w3.org/TR/xmlschema-1/#cos-nonambig) constraint.
+ */
+ static bool isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool);
+
+ /**
+ * Checks whether the given @p particle, which must be an xsd:all element,
+ * is valid according the UPA (http://www.w3.org/TR/xmlschema-1/#cos-nonambig) constraint.
+ * For xsd:all elements, we do not want to construct a state machine.
+ */
+ static bool isUPAConformXsdAll(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool);
+
+ /**
+ * Checks whether the given @p particle subsumes the given @p derivedParticle.
+ * (http://www.w3.org/TR/xmlschema-1/#cos-particle-restrict)
+ */
+ static bool subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdreference.cpp b/src/xmlpatterns/schema/qxsdreference.cpp
new file mode 100644
index 0000000..d98a405
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdreference.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdreference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdReference::isReference() const
+{
+ return true;
+}
+
+void XsdReference::setType(Type type)
+{
+ m_type = type;
+}
+
+XsdReference::Type XsdReference::type() const
+{
+ return m_type;
+}
+
+void XsdReference::setReferenceName(const QXmlName &referenceName)
+{
+ m_referenceName = referenceName;
+}
+
+QXmlName XsdReference::referenceName() const
+{
+ return m_referenceName;
+}
+
+void XsdReference::setSourceLocation(const QSourceLocation &location)
+{
+ m_sourceLocation = location;
+}
+
+QSourceLocation XsdReference::sourceLocation() const
+{
+ return m_sourceLocation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdreference_p.h b/src/xmlpatterns/schema/qxsdreference_p.h
new file mode 100644
index 0000000..028d190
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdreference_p.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdReference_H
+#define Patternist_XsdReference_H
+
+#include "qxsdterm_p.h"
+
+#include <QtXmlPatterns/QSourceLocation>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class for element and group reference resolving.
+ *
+ * For easy resolving of element and group references, we have this class
+ * that can be used as a place holder for the real element or group
+ * object it is referring to.
+ * So whenever the parser detects an element or group reference, it creates
+ * a XsdReference and returns it instead of the XsdElement or XsdModelGroup.
+ * During a later phase, the resolver will look for all XsdReferences
+ * in the schema and will replace them with their referring XsdElement or
+ * XsdModelGroup objects.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdReference : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdReference> Ptr;
+
+ /**
+ * Describes the type of the reference.
+ */
+ enum Type
+ {
+ Element, ///< The reference points to an element.
+ ModelGroup ///< The reference points to a model group.
+ };
+
+ /**
+ * Returns always @c true, used to avoid dynamic casts.
+ */
+ virtual bool isReference() const;
+
+ /**
+ * Sets the @p type of the reference.
+ *
+ * @see Type
+ */
+ void setType(Type type);
+
+ /**
+ * Returns the type of the reference.
+ */
+ Type type() const;
+
+ /**
+ * Sets the @p name of the referenced object.
+ *
+ * The name can either be a top-level element declaration
+ * or a top-level group declaration.
+ */
+ void setReferenceName(const QXmlName &ame);
+
+ /**
+ * Returns the name of the referenced object.
+ */
+ QXmlName referenceName() const;
+
+ /**
+ * Sets the source @p location where the reference is located.
+ */
+ void setSourceLocation(const QSourceLocation &location);
+
+ /**
+ * Returns the source location where the reference is located.
+ */
+ QSourceLocation sourceLocation() const;
+
+ private:
+ Type m_type;
+ QXmlName m_referenceName;
+ QSourceLocation m_sourceLocation;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschema.cpp b/src/xmlpatterns/schema/qxsdschema.cpp
new file mode 100644
index 0000000..cb766d1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschema.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschema_p.h"
+
+#include <QtCore/QReadLocker>
+#include <QtCore/QWriteLocker>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchema::XsdSchema(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+}
+
+XsdSchema::~XsdSchema()
+{
+}
+
+NamePool::Ptr XsdSchema::namePool() const
+{
+ return m_namePool;
+}
+
+void XsdSchema::setTargetNamespace(const QString &targetNamespace)
+{
+ m_targetNamespace = targetNamespace;
+}
+
+QString XsdSchema::targetNamespace() const
+{
+ return m_targetNamespace;
+}
+
+void XsdSchema::addElement(const XsdElement::Ptr &element)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_elements.insert(element->name(m_namePool), element);
+}
+
+XsdElement::Ptr XsdSchema::element(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elements.value(name);
+}
+
+XsdElement::List XsdSchema::elements() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elements.values();
+}
+
+void XsdSchema::addAttribute(const XsdAttribute::Ptr &attribute)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_attributes.insert(attribute->name(m_namePool), attribute);
+}
+
+XsdAttribute::Ptr XsdSchema::attribute(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributes.value(name);
+}
+
+XsdAttribute::List XsdSchema::attributes() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributes.values();
+}
+
+void XsdSchema::addType(const SchemaType::Ptr &type)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_types.insert(type->name(m_namePool), type);
+}
+
+SchemaType::Ptr XsdSchema::type(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_types.value(name);
+}
+
+SchemaType::List XsdSchema::types() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_types.values();
+}
+
+XsdSimpleType::List XsdSchema::simpleTypes() const
+{
+ QReadLocker locker(&m_lock);
+
+ XsdSimpleType::List retval;
+
+ const SchemaType::List types = m_types.values();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isSimpleType() && types.at(i)->isDefinedBySchema())
+ retval.append(types.at(i));
+ }
+
+ return retval;
+}
+
+XsdComplexType::List XsdSchema::complexTypes() const
+{
+ QReadLocker locker(&m_lock);
+
+ XsdComplexType::List retval;
+
+ const SchemaType::List types = m_types.values();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema())
+ retval.append(types.at(i));
+ }
+
+ return retval;
+}
+
+void XsdSchema::addAnonymousType(const SchemaType::Ptr &type)
+{
+ const QWriteLocker locker(&m_lock);
+
+ // search for not used anonymous type name
+ QXmlName typeName = type->name(m_namePool);
+ while (m_anonymousTypes.contains(typeName)) {
+ typeName = m_namePool->allocateQName(QString(), QLatin1String("merged_") + m_namePool->stringForLocalName(typeName.localName()), QString());
+ }
+
+ m_anonymousTypes.insert(typeName, type);
+}
+
+SchemaType::List XsdSchema::anonymousTypes() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_anonymousTypes.values();
+}
+
+void XsdSchema::addAttributeGroup(const XsdAttributeGroup::Ptr &group)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_attributeGroups.insert(group->name(m_namePool), group);
+}
+
+XsdAttributeGroup::Ptr XsdSchema::attributeGroup(const QXmlName name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributeGroups.value(name);
+}
+
+XsdAttributeGroup::List XsdSchema::attributeGroups() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributeGroups.values();
+}
+
+void XsdSchema::addElementGroup(const XsdModelGroup::Ptr &group)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_elementGroups.insert(group->name(m_namePool), group);
+}
+
+XsdModelGroup::Ptr XsdSchema::elementGroup(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elementGroups.value(name);
+}
+
+XsdModelGroup::List XsdSchema::elementGroups() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elementGroups.values();
+}
+
+void XsdSchema::addNotation(const XsdNotation::Ptr &notation)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_notations.insert(notation->name(m_namePool), notation);
+}
+
+XsdNotation::Ptr XsdSchema::notation(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_notations.value(name);
+}
+
+XsdNotation::List XsdSchema::notations() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_notations.values();
+}
+
+void XsdSchema::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_identityConstraints.insert(constraint->name(m_namePool), constraint);
+}
+
+XsdIdentityConstraint::Ptr XsdSchema::identityConstraint(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_identityConstraints.value(name);
+}
+
+XsdIdentityConstraint::List XsdSchema::identityConstraints() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_identityConstraints.values();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschema_p.h b/src/xmlpatterns/schema/qxsdschema_p.h
new file mode 100644
index 0000000..e63324e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschema_p.h
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchema_H
+#define Patternist_XsdSchema_H
+
+#include "qschematype_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdcomplextype_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdidentityconstraint_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdsimpletype_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QReadWriteLock>
+
+/**
+ * @defgroup Patternist_schema XML Schema Processing
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD schema object.
+ *
+ * The class provides access to all components of a parsed XSD.
+ *
+ * @note In the documentation of this class objects, which are direct
+ * children of the <em>schema</em> object, are called top-level objects.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSModel">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchema : public QSharedData, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchema> Ptr;
+ typedef QList<XsdSchema::Ptr> List;
+
+ /**
+ * Creates a new schema object.
+ *
+ * @param namePool The namepool that should be used for names of
+ * all schema components.
+ */
+ XsdSchema(const NamePool::Ptr &namePool);
+
+ /**
+ * Destroys the schema object.
+ */
+ ~XsdSchema();
+
+ /**
+ * Returns the namepool that is used for names of
+ * all schema components.
+ */
+ NamePool::Ptr namePool() const;
+
+ /**
+ * Sets the @p targetNamespace of the schema.
+ */
+ void setTargetNamespace(const QString &targetNamespace);
+
+ /**
+ * Returns the target namespace of the schema.
+ */
+ QString targetNamespace() const;
+
+ /**
+ * Adds a new top-level @p element to the schema.
+ *
+ * @param element The new element.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-element">Element Declaration</a>
+ */
+ void addElement(const XsdElement::Ptr &element);
+
+ /**
+ * Returns the top-level element of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdElement::Ptr element(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level elements.
+ */
+ XsdElement::List elements() const;
+
+ /**
+ * Adds a new top-level @p attribute to the schema.
+ *
+ * @param attribute The new attribute.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-attribute">Attribute Declaration</a>
+ */
+ void addAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Returns the top-level attribute of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdAttribute::Ptr attribute(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level attributes.
+ */
+ XsdAttribute::List attributes() const;
+
+ /**
+ * Adds a new top-level @p type to the schema.
+ * That can be a simple or a complex type.
+ *
+ * @param type The new type.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-datatype">Simple Type Declaration</a>
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-type">Complex Type Declaration</a>
+ */
+ void addType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the top-level type of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ SchemaType::Ptr type(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level types.
+ */
+ SchemaType::List types() const;
+
+ /**
+ * Returns the list of all top-level simple types.
+ */
+ XsdSimpleType::List simpleTypes() const;
+
+ /**
+ * Returns the list of all top-level complex types.
+ */
+ XsdComplexType::List complexTypes() const;
+
+ /**
+ * Adds an anonymous @p type to the schema.
+ * Anonymous types have no name and are declared
+ * locally inside an element object.
+ *
+ * @param type The new anonymous type.
+ */
+ void addAnonymousType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the list of all anonymous types.
+ */
+ SchemaType::List anonymousTypes() const;
+
+ /**
+ * Adds a new top-level attribute @p group to the schema.
+ *
+ * @param group The new attribute group.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-attributeGroup">Attribute Group Declaration</a>
+ */
+ void addAttributeGroup(const XsdAttributeGroup::Ptr &group);
+
+ /**
+ * Returns the top-level attribute group of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdAttributeGroup::Ptr attributeGroup(const QXmlName name) const;
+
+ /**
+ * Returns the list of all top-level attribute groups.
+ */
+ XsdAttributeGroup::List attributeGroups() const;
+
+ /**
+ * Adds a new top-level element @p group to the schema.
+ *
+ * @param group The new element group.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-namedModelGroup">Element Group Declaration</a>
+ */
+ void addElementGroup(const XsdModelGroup::Ptr &group);
+
+ /**
+ * Returns the top-level element group of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdModelGroup::Ptr elementGroup(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level element groups.
+ */
+ XsdModelGroup::List elementGroups() const;
+
+ /**
+ * Adds a new top-level @p notation to the schema.
+ *
+ * @param notation The new notation.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-notation">Notation Declaration</a>
+ */
+ void addNotation(const XsdNotation::Ptr &notation);
+
+ /**
+ * Returns the top-level notation of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdNotation::Ptr notation(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level notations.
+ */
+ XsdNotation::List notations() const;
+
+ /**
+ * Adds a new identity @p constraint to the schema.
+ */
+ void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint);
+
+ /**
+ * Returns the identity constraint with the given @p name
+ * or an empty pointer if none exist.
+ */
+ XsdIdentityConstraint::Ptr identityConstraint(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all identity constraints in this schema.
+ */
+ XsdIdentityConstraint::List identityConstraints() const;
+
+ private:
+ NamePool::Ptr m_namePool;
+ QString m_targetNamespace;
+ QHash<QXmlName, XsdElement::Ptr> m_elements;
+ QHash<QXmlName, XsdAttribute::Ptr> m_attributes;
+ QHash<QXmlName, SchemaType::Ptr> m_types;
+ QHash<QXmlName, SchemaType::Ptr> m_anonymousTypes;
+ QHash<QXmlName, XsdAttributeGroup::Ptr> m_attributeGroups;
+ QHash<QXmlName, XsdModelGroup::Ptr> m_elementGroups;
+ QHash<QXmlName, XsdNotation::Ptr> m_notations;
+ QHash<QXmlName, XsdIdentityConstraint::Ptr> m_identityConstraints;
+ mutable QReadWriteLock m_lock;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemachecker.cpp b/src/xmlpatterns/schema/qxsdschemachecker.cpp
new file mode 100644
index 0000000..0d16940
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker.cpp
@@ -0,0 +1,2061 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemachecker_p.h"
+
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qpatternplatform_p.h"
+#include "qqnamevalue_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qvaluefactory_p.h"
+#include "qxsdattributereference_p.h"
+#include "qxsdparticlechecker_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemaparsercontext_p.h"
+#include "qxsdschematypesfactory_p.h"
+#include "qxsdtypechecker_p.h"
+
+#include "qxsdschemachecker_helper.cpp"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaChecker::XsdSchemaChecker(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext)
+ : m_context(context)
+ , m_namePool(parserContext->namePool())
+ , m_schema(parserContext->schema())
+{
+ setupAllowedAtomicFacets();
+}
+
+XsdSchemaChecker::~XsdSchemaChecker()
+{
+}
+
+/*
+ * This method is called after the resolver has set the base type for every
+ * type and information about deriavtion and 'is simple type vs. is complex type'
+ * are available.
+ */
+void XsdSchemaChecker::basicCheck()
+{
+ // first check that there is no circular inheritance, only the
+ // wxsSuperType is used here
+ checkBasicCircularInheritances();
+
+ // check the basic constraints like simple type can not inherit from complex type etc.
+ checkBasicSimpleTypeConstraints();
+ checkBasicComplexTypeConstraints();
+}
+
+void XsdSchemaChecker::check()
+{
+ checkCircularInheritances();
+ checkInheritanceRestrictions();
+ checkSimpleDerivationRestrictions();
+ checkSimpleTypeConstraints();
+ checkComplexTypeConstraints();
+ checkDuplicatedAttributeUses();
+
+ checkElementConstraints();
+ checkAttributeConstraints();
+ checkAttributeUseConstraints();
+// checkElementDuplicates();
+}
+
+void XsdSchemaChecker::addComponentLocationHash(const ComponentLocationHash &hash)
+{
+ m_componentLocationHash.unite(hash);
+}
+
+/**
+ * Checks whether the @p otherType is the same as @p myType or if one of its
+ * ancestors is the same as @p myType.
+ */
+static bool matchesType(const SchemaType::Ptr &myType, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> visitedTypes)
+{
+ bool retval = false;
+
+ if (otherType) {
+ if (visitedTypes.contains(otherType)) {
+ return true;
+ } else {
+ visitedTypes.insert(otherType);
+ }
+ // simple types can have different varieties, so we have to check each of them
+ if (otherType->isSimpleType()) {
+ const XsdSimpleType::Ptr simpleType = otherType;
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ // for atomic type we use the same test as in SchemaType::wxsTypeMatches
+ retval = (myType == simpleType ? true : matchesType(myType, simpleType->wxsSuperType(), visitedTypes));
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ // for list type we test against the itemType property
+ retval = (myType == simpleType->itemType() ? true : matchesType(myType, simpleType->itemType()->wxsSuperType(), visitedTypes));
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ // for union type we test against each member type
+ const XsdSimpleType::List members = simpleType->memberTypes();
+ for (int i = 0; i < members.count(); ++i) {
+ if (myType == members.at(i) ? true : matchesType(myType, members.at(i)->wxsSuperType(), visitedTypes)) {
+ retval = true;
+ break;
+ }
+ }
+ } else {
+ // reached xsAnySimple type whichs category is None
+ retval = false;
+ }
+ } else {
+ // if no simple type we handle it like in SchemaType::wxsTypeMatches
+ retval = (myType == otherType ? true : matchesType(myType, otherType->wxsSuperType(), visitedTypes));
+ }
+ } else // if otherType is null it doesn't match
+ retval = false;
+
+ return retval;
+}
+
+/**
+ * Checks whether there is a circular inheritance for the union inheritance.
+ */
+static bool hasCircularUnionInheritance(const XsdSimpleType::Ptr &type, const SchemaType::Ptr &otherType, NamePool::Ptr &namePool)
+{
+ if (type == otherType) {
+ return true;
+ }
+
+ if (!otherType->isSimpleType() || !otherType->isDefinedBySchema()) {
+ return false;
+ }
+
+ const XsdSimpleType::Ptr simpleOtherType = otherType;
+
+ if (simpleOtherType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const XsdSimpleType::List memberTypes = simpleOtherType->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ if (otherType->wxsSuperType() == type) {
+ return true;
+ }
+ if (hasCircularUnionInheritance(type, memberTypes.at(i), namePool)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static inline bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> &visitedTypes, SchemaType::Ptr &conflictingType)
+{
+ if (!otherType)
+ return false;
+
+ if (visitedTypes.contains(otherType)) { // inheritance loop detected
+ conflictingType = otherType;
+ return true;
+ } else {
+ visitedTypes.insert(otherType);
+ }
+
+ if (type == otherType)
+ return true;
+
+ return wxsTypeMatches(type, otherType->wxsSuperType(), visitedTypes, conflictingType);
+}
+
+void XsdSchemaChecker::checkBasicCircularInheritances()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ const QSourceLocation location = sourceLocationForType(type);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)
+
+ // check normal base type inheritance
+ QSet<SchemaType::Ptr> visitedTypes;
+ SchemaType::Ptr conflictingType;
+
+ if (wxsTypeMatches(type, type->wxsSuperType(), visitedTypes, conflictingType)) {
+ if (conflictingType)
+ m_context->error(QtXmlPatterns::tr("%1 has inheritance loop in its base type %2.")
+ .arg(formatType(m_namePool, type))
+ .arg(formatType(m_namePool, conflictingType)),
+ XsdSchemaContext::XSDError, location);
+ else
+ m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
+
+ return;
+ }
+ }
+}
+
+void XsdSchemaChecker::checkCircularInheritances()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ const QSourceLocation location = sourceLocationForType(type);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)
+
+ // check normal base type inheritance
+ QSet<SchemaType::Ptr> visitedTypes;
+ if (matchesType(type, type->wxsSuperType(), visitedTypes)) {
+ m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // check union member inheritance
+ if (type->isSimpleType() && type->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleType = type;
+ if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const XsdSimpleType::List memberTypes = simpleType->memberTypes();
+ for (int j = 0; j < memberTypes.count(); ++j) {
+ if (hasCircularUnionInheritance(simpleType, memberTypes.at(j), m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Circular inheritance of union %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkInheritanceRestrictions()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ const QSourceLocation location = sourceLocationForType(type);
+
+ // check inheritance restrictions given by final property of base class
+ const SchemaType::Ptr baseType = type->wxsSuperType();
+ if (baseType->isDefinedBySchema()) {
+ if ((type->derivationMethod() == SchemaType::DerivationRestriction) && (baseType->derivationConstraints() & SchemaType::RestrictionConstraint)) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by restriction as the latter defines it as final.")
+ .arg(formatType(m_namePool, type))
+ .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
+ return;
+ } else if ((type->derivationMethod() == SchemaType::DerivationExtension) && (baseType->derivationConstraints() & SchemaType::ExtensionConstraint)) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by extension as the latter defines it as final.")
+ .arg(formatType(m_namePool, type))
+ .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkBasicSimpleTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isSimpleType())
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = type;
+
+ const QSourceLocation location = sourceLocation(simpleType);
+
+ // check inheritance restrictions of simple type defined by schema constraints
+ const SchemaType::Ptr baseType = simpleType->wxsSuperType();
+
+ if (baseType->isComplexType() && (simpleType->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Base type of simple type %1 cannot be complex type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (baseType == BuiltinTypes::xsAnyType) {
+ if (type->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 cannot have direct base type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, BuiltinTypes::xsAnyType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkSimpleTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isSimpleType())
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = type;
+
+ const QSourceLocation location = sourceLocation(simpleType);
+
+ if (simpleType->category() == XsdSimpleType::None) {
+ // additional checks
+ // check that no user defined type has xs:AnySimpleType as base type (except xs:AnyAtomicType)
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ if (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleType->wxsSuperType())),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ // check that no user defined type has xs:AnyAtomicType as base type
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleType->wxsSuperType())),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e37310
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ // 1.1
+ if ((simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeAtomic) && (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 can only have simple atomic type as base type.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ }
+ // 1.2
+ if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 cannot derive from %2 as the latter defines restriction as final.")
+ .arg(formatType(m_namePool, simpleType->wxsSuperType()))
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ }
+
+ // 1.3
+ // checked by checkConstrainingFacets already
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ const AnySimpleType::Ptr itemType = simpleType->itemType();
+
+ // 2.1 or @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
+ if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
+ m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.1 second part
+ if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+ const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
+ for (int j = 0; j < memberTypes.count(); ++j) {
+ if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) {
+ m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic.").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+
+ // 2.2.1
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+
+ // 2.2.1.1
+ if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.1.2
+ const XsdFacet::Hash facets = simpleType->facets();
+ XsdFacet::HashIterator it(facets);
+
+ bool invalidFacetFound = false;
+ while (it.hasNext()) {
+ it.next();
+ if (it.key() != XsdFacet::WhiteSpace) {
+ invalidFacetFound = true;
+ break;
+ }
+ }
+
+ if (invalidFacetFound) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 is only allowed to have %2 facet.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword("whiteSpace")),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ } else { // 2.2.2
+ // 2.2.2.1
+ if (simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeList) {
+ m_context->error(QtXmlPatterns::tr("Base type of simple type %1 must have variety of type list.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.2
+ if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
+ m_context->error(QtXmlPatterns::tr("Base type of simple type %1 has defined derivation by restriction as final.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.3
+ if (!XsdSchemaHelper::isSimpleDerivationOk(itemType, XsdSimpleType::Ptr(simpleType->wxsSuperType())->itemType(), SchemaType::DerivationConstraints())) {
+ m_context->error(QtXmlPatterns::tr("Item type of base type does not match item type of %1.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.4
+ const XsdFacet::Hash facets = simpleType->facets();
+ XsdFacet::HashIterator it(facets);
+
+ bool invalidFacetFound = false;
+ XsdFacet::Type invalidFacetType = XsdFacet::None;
+ while (it.hasNext()) {
+ it.next();
+ const XsdFacet::Type facetType = it.key();
+ if (facetType != XsdFacet::Length &&
+ facetType != XsdFacet::MinimumLength &&
+ facetType != XsdFacet::MaximumLength &&
+ facetType != XsdFacet::WhiteSpace &&
+ facetType != XsdFacet::Pattern &&
+ facetType != XsdFacet::Enumeration) {
+ invalidFacetType = facetType;
+ invalidFacetFound = true;
+ break;
+ }
+ }
+
+ if (invalidFacetFound) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.5
+ // TODO: check value constraints
+ }
+
+
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { // 3.1.1
+ // 3.3.1.1
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr memberType = memberTypes.at(i);
+
+ if (memberType->derivationConstraints() & XsdSimpleType::UnionConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, memberType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // 3.3.1.2
+ if (!simpleType->facets().isEmpty()) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to have any facets.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ } else {
+ // 3.1.2.1
+ if (simpleType->wxsSuperType()->category() != SchemaType::SimpleTypeUnion) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 must have variety of union.")
+ .arg(formatType(m_namePool, simpleType->wxsSuperType()))
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 3.1.2.2
+ if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::DerivationRestriction) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute.")
+ .arg(formatType(m_namePool, simpleType->wxsSuperType()))
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatAttribute("final")),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ //3.1.2.3
+ if (simpleType->wxsSuperType()->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleBaseType(simpleType->wxsSuperType());
+
+ AnySimpleType::List baseMemberTypes = simpleBaseType->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr memberType = memberTypes.at(i);
+ const AnySimpleType::Ptr baseMemberType = baseMemberTypes.at(i);
+
+ if (!XsdSchemaHelper::isSimpleDerivationOk(memberType, baseMemberType, SchemaType::DerivationConstraints())) {
+ m_context->error(QtXmlPatterns::tr("Member type %1 cannot be derived from member type %2 of %3's base type %4.")
+ .arg(formatType(m_namePool, memberType))
+ .arg(formatType(m_namePool, baseMemberType))
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleBaseType)),
+ XsdSchemaContext::XSDError, location);
+ }
+ }
+ }
+
+ // 3.1.2.4
+ const XsdFacet::Hash facets = simpleType->facets();
+ XsdFacet::HashIterator it(facets);
+
+ bool invalidFacetFound = false;
+ XsdFacet::Type invalidFacetType = XsdFacet::None;
+ while (it.hasNext()) {
+ it.next();
+ const XsdFacet::Type facetType = it.key();
+ if (facetType != XsdFacet::Pattern &&
+ facetType != XsdFacet::Enumeration) {
+ invalidFacetType = facetType;
+ invalidFacetFound = true;
+ break;
+ }
+ }
+
+ if (invalidFacetFound) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 3.1.2.5
+ // TODO: check value constraints
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkBasicComplexTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isComplexType() || !type->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = type;
+
+ const QSourceLocation location = sourceLocation(complexType);
+
+ // check inheritance restrictions of complex type defined by schema constraints
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 2)
+ if (baseType->isSimpleType() && (complexType->derivationMethod() != XsdComplexType::DerivationExtension)) {
+ m_context->error(QtXmlPatterns::tr("Derivation method of %1 must be extension because the base type %2 is a simple type.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+}
+
+void XsdSchemaChecker::checkComplexTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isComplexType() || !type->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = type;
+
+ const QSourceLocation location = sourceLocation(complexType);
+
+ if (complexType->contentType()->particle()) {
+ XsdElement::Ptr duplicatedElement;
+ if (XsdParticleChecker::hasDuplicatedElements(complexType->contentType()->particle(), m_namePool, duplicatedElement)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 has duplicated element %2 in its content model.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatKeyword(duplicatedElement->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (!XsdParticleChecker::isUPAConform(complexType->contentType()->particle(), m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 has non-deterministic content.")
+ .arg(formatType(m_namePool, complexType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // check inheritance restrictions of complex type defined by schema constraints
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends
+ if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) {
+ if (baseType->isComplexType() && baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType = baseType;
+
+ // we can skip 1.1 here, as it is tested in checkInheritanceRestrictions() already
+
+ // 1.2 and 1.3
+ QString errorMsg;
+ if (!XsdSchemaHelper::isValidAttributeUsesExtension(complexType->attributeUses(), complexBaseType->attributeUses(),
+ complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 1.4
+ bool validContentType = false;
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (complexType->contentType()->simpleType() == complexBaseType->contentType()->simpleType()) {
+ validContentType = true; // 1.4.1
+ }
+ } else if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ validContentType = true; // 1.4.2
+ } else { // 1.4.3
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { // 1.4.3.1
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ validContentType = true; // 1.4.3.2.1
+ } else { // 1.4.3.2.2
+ if (complexType->contentType()->particle()) { // our own check
+ if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) ||
+ (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { // 1.4.3.2.2.1
+ if (isValidParticleExtension(complexType->contentType()->particle(), complexBaseType->contentType()->particle())) {
+ validContentType = true; // 1.4.3.2.2.2
+ }
+ }
+ }
+ // 1.4.3.2.2.3 and 1.4.3.2.2.4 handle 'open content' that we do not support yet
+ }
+ }
+ }
+
+ // 1.5 WTF?!?
+
+ if (!validContentType) {
+ m_context->error(QtXmlPatterns::tr("Content model of complex type %1 is not a valid extension of content model of %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ } else if (baseType->isSimpleType()) {
+ // 2.1
+ if (complexType->contentType()->variety() != XsdComplexType::ContentType::Simple) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 must have simple content.")
+ .arg(formatType(m_namePool, complexType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (complexType->contentType()->simpleType() != baseType) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 must have the same simple type as its base class %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2 tested in checkInheritanceRestrictions() already
+ }
+ } else if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e21402
+ const SchemaType::Ptr baseType(complexType->wxsSuperType());
+
+ bool derivationOk = false;
+ QString errorMsg;
+
+ // we can partly skip 1 here, as it is tested in checkInheritanceRestrictions() already
+ if (baseType->isComplexType()) {
+
+ // 2.1
+ if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
+ derivationOk = true;
+ }
+
+ if (baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ // 2.2.1
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ // 2.2.2.1
+ if (XsdSchemaHelper::isSimpleDerivationOk(complexType->contentType()->simpleType(), complexBaseType->contentType()->simpleType(), SchemaType::DerivationConstraints()))
+ derivationOk = true;
+
+ // 2.2.2.2
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+ if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
+ derivationOk = true;
+ }
+ }
+
+ // 2.3.1
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ // 2.3.2.1
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty)
+ derivationOk = true;
+
+ // 2.3.2.2
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+ if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
+ derivationOk = true;
+ }
+ }
+
+ // 2.4.1.1
+ if (((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) &&
+ (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) ||
+ // 2.4.1.2
+ (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
+
+ // 2.4.2
+ if (XsdParticleChecker::subsumes(complexBaseType->contentType()->particle(), complexType->contentType()->particle(), m_context, errorMsg))
+ derivationOk = true;
+ }
+ }
+ }
+
+ if (!derivationOk) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 cannot be derived from base type %2%3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(errorMsg.isEmpty() ? QString() : QLatin1String(": ") + errorMsg),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ QString errorMsg;
+ if (!XsdSchemaHelper::isValidAttributeUsesRestriction(complexType->attributeUses(), complexBaseType->attributeUses(),
+ complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+
+ // check that complex type with simple content is not allowed to inherit from
+ // built in complex type xs:AnyType
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 with simple content cannot be derived from complex base type %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkSimpleDerivationRestrictions()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (type->isComplexType())
+ continue;
+
+ if (type->category() != SchemaType::SimpleTypeList && type->category() != SchemaType::SimpleTypeUnion)
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = type;
+ const QSourceLocation location = sourceLocation(simpleType);
+
+ // check all simple types derived by list
+ if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ const AnySimpleType::Ptr itemType = simpleType->itemType();
+
+ if (itemType->isComplexType()) {
+ m_context->error(QtXmlPatterns::tr("Item type of simple type %1 cannot be a complex type.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+
+ if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+ if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleItemType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
+ if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
+ m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+ const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
+ for (int j = 0; j < memberTypes.count(); ++j) {
+ if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) {
+ m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic.").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+ }
+
+ // check all simple types derived by union
+ if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr memberType = memberTypes.at(i);
+
+ if (memberType->isComplexType()) {
+ m_context->error(QtXmlPatterns::tr("Member type of simple type %1 cannot be a complex type.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#cos-no-circular-unions
+ if (simpleType->name(m_namePool) == memberType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to have a member type with the same name as itself.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (memberType->isSimpleType() && memberType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleMemberType = memberType;
+ if (simpleMemberType->derivationConstraints() & XsdSimpleType::UnionConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleMemberType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkConstrainingFacets()
+{
+ // first the global simple types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isSimpleType()) || !(types.at(i)->isDefinedBySchema()))
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = types.at(i);
+ checkConstrainingFacets(simpleType->facets(), simpleType);
+ }
+
+ // and afterwards all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (!(anonymousTypes.at(i)->isSimpleType()) || !(anonymousTypes.at(i)->isDefinedBySchema()))
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = anonymousTypes.at(i);
+ checkConstrainingFacets(simpleType->facets(), simpleType);
+ }
+}
+
+void XsdSchemaChecker::checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType)
+{
+ if (facets.isEmpty())
+ return;
+
+ SchemaType::Ptr comparableBaseType;
+ if (!simpleType->wxsSuperType()->isDefinedBySchema())
+ comparableBaseType = simpleType->wxsSuperType();
+ else
+ comparableBaseType = simpleType->primitiveType();
+
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));
+
+ // start checks
+ if (facets.contains(XsdFacet::Length)) {
+ const XsdFacet::Ptr lengthFacet = facets.value(XsdFacet::Length);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr lengthValue = lengthFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();
+
+ bool foundSuperMinimumLength = false;
+ SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ while (baseType) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
+ if (baseFacets.contains(XsdFacet::MinimumLength) && !baseFacets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MinimumLength)->value());
+ if (minLengthValue->toInteger() == superValue->toInteger()) {
+ foundSuperMinimumLength = true;
+ break;
+ }
+ }
+
+ baseType = baseType->wxsSuperType();
+ }
+
+ if ((minLengthValue->toInteger() > lengthValue->toInteger()) || !foundSuperMinimumLength) {
+ m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
+ .arg(formatKeyword("length"))
+ .arg(formatKeyword("minLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
+
+ bool foundSuperMaximumLength = false;
+ SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ while (baseType) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
+ if (baseFacets.contains(XsdFacet::MaximumLength) && !baseFacets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MaximumLength)->value());
+ if (maxLengthValue->toInteger() == superValue->toInteger()) {
+ foundSuperMaximumLength = true;
+ break;
+ }
+ }
+
+ baseType = baseType->wxsSuperType();
+ }
+
+ if ((maxLengthValue->toInteger() < lengthValue->toInteger()) || !foundSuperMaximumLength) {
+ m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
+ .arg(formatKeyword("length"))
+ .arg(formatKeyword("maxLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#length-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::Length)->value();
+ if (lengthValue->toInteger() != baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must have the same value as %2 facet of base type.")
+ .arg(formatKeyword("length"))
+ .arg(formatKeyword("length")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();
+
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minLength-less-than-equal-to-maxLength
+ if (maxLengthValue->toInteger() < minLengthValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
+ .arg(formatKeyword("minLength"))
+ .arg(formatKeyword("maxLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
+ //TODO: check parent facets
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MinimumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::MinimumLength)->value();
+ if (minLengthValue->toInteger() < baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be equal or greater than %2 facet of base type.")
+ .arg(formatKeyword("minLength"))
+ .arg(formatKeyword("minLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxLength-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MaximumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue(baseFacets.value(XsdFacet::MaximumLength)->value());
+ if (maxLengthValue->toInteger() > baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxLength"))
+ .arg(formatKeyword("maxLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ // we keep the patterns in separated facets
+ // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-patterns
+
+ // @see http://www.w3.org/TR/xmlschema-2/#cvc-pattern-valid
+ const XsdFacet::Ptr patternFacet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = patternFacet->multiValue();
+
+ for (int i = 0; i < multiValue.count(); ++i) {
+ const DerivedString<TypeString>::Ptr value = multiValue.at(i);
+ const QRegExp exp = PatternPlatform::parsePattern(value->stringValue(), m_context, &reflection);
+ if (!exp.isValid()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet contains invalid regular expression").arg(formatKeyword("pattern.")), XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-enumerations
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ if (BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) {
+ const AtomicValue::List notationNames = facet->multiValue();
+ for (int k = 0; k < notationNames.count(); ++k) {
+ const QNameValue::Ptr notationName = notationNames.at(k);
+ if (!m_schema->notation(notationName->qName())) {
+ m_context->error(QtXmlPatterns::tr("Unknown notation %1 used in %2 facet.")
+ .arg(formatKeyword(m_namePool, notationName->qName()))
+ .arg(formatKeyword("enumeration")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ }
+ }
+ } else if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType)) {
+ } else {
+ const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(simpleType));
+
+ const AnySimpleType::Ptr baseType = simpleType->wxsSuperType();
+ const XsdFacet::Hash baseFacets = XsdTypeChecker::mergedFacetsForType(baseType, m_context);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int k = 0; k < multiValue.count(); ++k) {
+ const QString stringValue = multiValue.at(k)->as<DerivedString<TypeString> >()->stringValue();
+ const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, baseFacets);
+
+ QString errorMsg;
+ if (!checker.isValidString(actualValue, baseType, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet contains invalid value %2: %3.")
+ .arg(formatKeyword("enumeration"))
+ .arg(formatData(stringValue))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::WhiteSpace)) {
+ const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace);
+ const DerivedString<TypeString>::Ptr whiteSpaceValue = whiteSpaceFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#whiteSpace-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::WhiteSpace)) {
+ const QString value = whiteSpaceValue->stringValue();
+ const QString baseValue = DerivedString<TypeString>::Ptr(baseFacets.value(XsdFacet::WhiteSpace)->value())->stringValue();
+ if (value == XsdSchemaToken::toString(XsdSchemaToken::Replace) || value == XsdSchemaToken::toString(XsdSchemaToken::Preserve)) {
+ if (baseValue == XsdSchemaToken::toString(XsdSchemaToken::Collapse)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 or %3 if %4 facet of base type is %5.")
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("replace"))
+ .arg(formatData("preserve"))
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("collapse")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ if (value == XsdSchemaToken::toString(XsdSchemaToken::Preserve) && baseValue == XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 if %3 facet of base type is %4.")
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("preserve"))
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("replace")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-equal-to-maxInclusive
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);
+
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxInclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
+ .arg(formatKeyword("maxInclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-maxExclusive
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-equal-to-maxExclusive
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxExclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("minInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("minExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-minExclusive
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("minInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-maxInclusive
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("minExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-maxExclusive
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("minInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("minExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#totalDigits-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();
+
+ if (totalDigitsValue->toInteger() > baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("totalDigits"))
+ .arg(formatKeyword("totalDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::FractionDigits)) {
+ const XsdFacet::Ptr fractionDigitsFacet = facets.value(XsdFacet::FractionDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr fractionDigitsValue = fractionDigitsFacet->value();
+
+ // http://www.w3.org/TR/xmlschema-2/#fractionDigits-totalDigits
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();
+
+ if (fractionDigitsValue->toInteger() > totalDigitsValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
+ .arg(formatKeyword("fractionDigits"))
+ .arg(formatKeyword("totalDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#fractionDigits-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::FractionDigits)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::FractionDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();
+
+ if (fractionDigitsValue->toInteger() > baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("fractionDigits"))
+ .arg(formatKeyword("fractionDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+
+
+ // check whether facets are allowed for simple types variety
+ if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeAtomic) {
+ if (simpleType->primitiveType()) {
+ const QXmlName primitiveTypeName = simpleType->primitiveType()->name(m_namePool);
+ if (m_allowedAtomicFacets.contains(primitiveTypeName)) {
+ const QSet<XsdFacet::Type> allowedFacets = m_allowedAtomicFacets.value(primitiveTypeName);
+ QSet<XsdFacet::Type> availableFacets = facets.keys().toSet();
+
+ if (!availableFacets.subtract(allowedFacets).isEmpty()) {
+ m_context->error(QtXmlPatterns::tr("Simple type contains not allowed facet %1.")
+ .arg(formatKeyword(XsdFacet::typeName(availableFacets.toList().first()))),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeList) {
+ if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) ||
+ facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) ||
+ facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits))
+ {
+ m_context->error(QtXmlPatterns::tr("%1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list.")
+ .arg(formatKeyword("maxInclusive"))
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("totalDigits"))
+ .arg(formatKeyword("fractionDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ }
+ } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeUnion) {
+ if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) ||
+ facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) ||
+ facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits) ||
+ facets.contains(XsdFacet::MinimumLength) || facets.contains(XsdFacet::MaximumLength) ||
+ facets.contains(XsdFacet::Length) || facets.contains(XsdFacet::WhiteSpace))
+ {
+ m_context->error(QtXmlPatterns::tr("Only %1 and %2 facets are allowed when derived by union.")
+ .arg(formatKeyword("pattern"))
+ .arg(formatKeyword("enumeration")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ }
+ }
+
+ // check whether value of facet matches the value space of the simple types base type
+ const SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ if (!baseType->isDefinedBySchema()) {
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));
+
+ XsdFacet::HashIterator it(facets);
+ while (it.hasNext()) {
+ it.next();
+ const XsdFacet::Ptr facet = it.value();
+ if (facet->type() == XsdFacet::MaximumInclusive ||
+ facet->type() == XsdFacet::MaximumExclusive ||
+ facet->type() == XsdFacet::MinimumInclusive ||
+ facet->type() == XsdFacet::MinimumExclusive) {
+ const DerivedString<TypeString>::Ptr stringValue = facet->value();
+ const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue->stringValue(), baseType, m_context, &reflection);
+ if (value->hasError()) {
+ m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(facet->type())))
+ .arg(formatData(stringValue->stringValue())),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#enumeration-valid-restriction
+ if (facet->type() == XsdFacet::Enumeration && baseType != BuiltinTypes::xsNOTATION) {
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString stringValue = DerivedString<TypeString>::Ptr(multiValue.at(j))->stringValue();
+ const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue, baseType, m_context, &reflection);
+ if (value->hasError()) {
+ m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(XsdFacet::Enumeration)))
+ .arg(formatData(stringValue)),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkDuplicatedAttributeUses()
+{
+ // first all global attribute groups
+ const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ const XsdAttributeGroup::Ptr attributeGroup = attributeGroups.at(i);
+ const XsdAttributeUse::List uses = attributeGroup->attributeUses();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
+ XsdAttribute::Ptr conflictingAttribute;
+ if (hasDuplicatedAttributeUses(uses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 twice.")
+ .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
+ if (hasMultipleIDAttributeUses(uses)) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 contains two different attributes that both have types derived from %2.")
+ .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
+ return;
+ }
+
+ if (hasConstraintIDAttributeUse(uses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3.")
+ .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
+ return;
+ }
+ }
+
+ // then the global and anonymous complex types
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
+ XsdAttribute::Ptr conflictingAttribute;
+ if (hasDuplicatedAttributeUses(attributeUses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 twice.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
+ if (hasMultipleIDAttributeUses(attributeUses)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 contains two different attributes that both have types derived from %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ if (hasConstraintIDAttributeUse(attributeUses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+}
+
+void XsdSchemaChecker::checkElementConstraints()
+{
+ const QSet<XsdElement::Ptr> elements = collectAllElements(m_schema);
+ QSetIterator<XsdElement::Ptr> it(elements);
+ while (it.hasNext()) {
+ const XsdElement::Ptr element = it.next();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct
+
+ // 2 and xs:ID check
+ if (element->valueConstraint()) {
+ const SchemaType::Ptr type = element->type();
+
+ AnySimpleType::Ptr targetType;
+ if (type->isSimpleType() && type->category() == SchemaType::SimpleTypeAtomic) {
+ targetType = type;
+
+ // if it is a XsdSimpleType, use its primitive type as target type
+ if (type->isDefinedBySchema())
+ targetType = XsdSimpleType::Ptr(type)->primitiveType();
+
+ } else if (type->isComplexType() && type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(type);
+
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ const AnySimpleType::Ptr simpleType = complexType->contentType()->simpleType();
+ if (simpleType->category() == AnySimpleType::SimpleTypeAtomic) {
+ targetType = simpleType;
+
+ if (simpleType->isDefinedBySchema())
+ targetType = XsdSimpleType::Ptr(simpleType)->primitiveType();
+ }
+ } else if (complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed) {
+ m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its base type is complex.")
+ .arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ }
+ if ((targetType == BuiltinTypes::xsID) || BuiltinTypes::xsID->wxsTypeMatches(type)) {
+ m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its type is derived from %2.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+
+ if (type->isSimpleType()) {
+ QString errorMsg;
+ if (!isValidValue(element->valueConstraint()->value(), type, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ } else if (type->isComplexType() && type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(type);
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ QString errorMsg;
+ if (!isValidValue(element->valueConstraint()->value(), complexType->contentType()->simpleType(), errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ }
+ }
+ }
+
+ if (!element->substitutionGroupAffiliations().isEmpty()) {
+ // 3
+ if (!element->scope() || element->scope()->variety() != XsdElement::Scope::Global) {
+ m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have substitution group affiliation as it is no global element.").arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+
+ // 4
+ const XsdElement::List affiliations = element->substitutionGroupAffiliations();
+ for (int i = 0; i < affiliations.count(); ++i) {
+ const XsdElement::Ptr affiliation = affiliations.at(i);
+
+ bool derivationOk = false;
+ if (element->type()->isComplexType() && affiliation->type()->isComplexType()) {
+ if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
+ derivationOk = true;
+ }
+ }
+ if (element->type()->isComplexType() && affiliation->type()->isSimpleType()) {
+ if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
+ derivationOk = true;
+ }
+ }
+ if (element->type()->isSimpleType()) {
+ if (XsdSchemaHelper::isSimpleDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
+ derivationOk = true;
+ }
+ }
+
+ if (!derivationOk) {
+ m_context->error(QtXmlPatterns::tr("Type of element %1 cannot be derived from type of substitution group affiliation.").arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ }
+
+ // 5 was checked in XsdSchemaResolver::resolveSubstitutionGroupAffiliations() already
+ }
+ }
+}
+
+void XsdSchemaChecker::checkAttributeConstraints()
+{
+ // all global attributes
+ XsdAttribute::List attributes = m_schema->attributes();
+
+ // and all local attributes
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ if (!types.at(i)->isComplexType() || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType(types.at(i));
+ const XsdAttributeUse::List uses = complexType->attributeUses();
+ for (int j = 0; j < uses.count(); ++j)
+ attributes.append(uses.at(j)->attribute());
+ }
+
+ for (int i = 0; i < attributes.count(); ++i) {
+ const XsdAttribute::Ptr attribute = attributes.at(i);
+
+ if (!attribute->valueConstraint())
+ continue;
+
+ if (attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Default || attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) {
+ const SchemaType::Ptr type = attribute->type();
+
+ QString errorMsg;
+ if (!isValidValue(attribute->valueConstraint()->value(), attribute->type(), errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Value constraint of attribute %1 is not of attributes type: %2.")
+ .arg(formatKeyword(attribute->displayName(m_namePool)))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(attribute));
+ return;
+ }
+ }
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(attribute->type())) {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 has value constraint but has type derived from %2.")
+ .arg(formatKeyword(attribute->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(attribute));
+ return;
+ }
+ }
+}
+
+bool XsdSchemaChecker::isValidValue(const QString &stringValue, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (BuiltinTypes::xsAnySimpleType->name(m_namePool) == type->name(m_namePool))
+ return true; // no need to check xs:anyType content
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context);
+ const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, facets);
+
+ const XsdTypeChecker checker(m_context, QVector<QXmlName>(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1));
+ return checker.isValidString(actualValue, type, errorMsg);
+}
+
+void XsdSchemaChecker::checkAttributeUseConstraints()
+{
+ XsdComplexType::List complexTypes;
+
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ if (type->isComplexType() && type->isDefinedBySchema())
+ complexTypes.append(XsdComplexType::Ptr(type));
+ }
+
+ for (int i = 0; i < complexTypes.count(); ++i) {
+ const XsdComplexType::Ptr complexType(complexTypes.at(i));
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+ if (!baseType || !baseType->isComplexType() || !baseType->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+ QHash<QXmlName, XsdAttributeUse::Ptr> lookupHash;
+ for (int j = 0; j < attributeUses.count(); ++j)
+ lookupHash.insert(attributeUses.at(j)->attribute()->name(m_namePool), attributeUses.at(j));
+
+ const XsdAttributeUse::List baseAttributeUses = complexBaseType->attributeUses();
+ for (int j = 0; j < baseAttributeUses.count(); ++j) {
+ const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(j);
+
+ if (lookupHash.contains(baseAttributeUse->attribute()->name(m_namePool))) {
+ const XsdAttributeUse::Ptr attributeUse = lookupHash.value(baseAttributeUse->attribute()->name(m_namePool));
+
+ if (baseAttributeUse->useType() == XsdAttributeUse::RequiredUse) {
+ if (attributeUse->useType() == XsdAttributeUse::OptionalUse || attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
+ m_context->error(QtXmlPatterns::tr("%1 attribute in derived complex type must be %2 like in base type.")
+ .arg(formatAttribute("use"))
+ .arg(formatData("required")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+
+ if (baseAttributeUse->valueConstraint()) {
+ if (baseAttributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
+ if (!attributeUse->valueConstraint()) {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint like in base type.")
+ .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
+ .arg(formatData("fixed")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ } else {
+ if (attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
+ const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(complexType));
+ if (!checker.valuesAreEqual(attributeUse->valueConstraint()->value(), baseAttributeUse->valueConstraint()->value(), attributeUse->attribute()->type())) {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have the same %2 value constraint like in base type.")
+ .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
+ .arg(formatData("fixed")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ } else {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint.")
+ .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
+ .arg(formatData("fixed")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // additional check that process content property of attribute wildcard in derived type is
+ // not weaker than the wildcard in base type
+ const XsdWildcard::Ptr baseWildcard(complexBaseType->attributeWildcard());
+ const XsdWildcard::Ptr derivedWildcard(complexType->attributeWildcard());
+ if (baseWildcard && derivedWildcard) {
+ if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, derivedWildcard)) {
+ m_context->error(QtXmlPatterns::tr("processContent of base wildcard must be weaker than derived wildcard."), XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkElementDuplicates()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isComplexType() || !type->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType(type);
+
+ if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) || (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
+ DuplicatedElementMap elementMap;
+ DuplicatedWildcardMap wildcardMap;
+
+ checkElementDuplicates(complexType->contentType()->particle(), elementMap, wildcardMap);
+ }
+ }
+}
+
+void XsdSchemaChecker::checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap)
+{
+ if (particle->term()->isElement()) {
+ const XsdElement::Ptr element(particle->term());
+
+ if (elementMap.contains(element->name(m_namePool))) {
+ if (element->type() != elementMap.value(element->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
+ .arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ } else {
+ elementMap.insert(element->name(m_namePool), element->type());
+ }
+
+ // check substitution group affiliation
+ const XsdElement::List substElements = element->substitutionGroupAffiliations();
+ for (int i = 0; i < substElements.count(); ++i) {
+ const XsdElement::Ptr substElement = substElements.at(i);
+ if (elementMap.contains(substElement->name(m_namePool))) {
+ if (substElement->type() != elementMap.value(substElement->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
+ .arg(formatKeyword(substElement->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ } else {
+ elementMap.insert(substElement->name(m_namePool), substElement->type());
+ }
+ }
+ } else if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i)
+ checkElementDuplicates(particles.at(i), elementMap, wildcardMap);
+ } else if (particle->term()->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(particle->term());
+
+ bool error = false;
+ if (!wildcardMap.contains(wildcard->namespaceConstraint()->variety())) {
+ if (!wildcardMap.isEmpty())
+ error = true;
+ } else {
+ const XsdWildcard::Ptr otherWildcard = wildcardMap.value(wildcard->namespaceConstraint()->variety());
+ if ((wildcard->processContents() != otherWildcard->processContents()) || (wildcard->namespaceConstraint()->namespaces() != otherWildcard->namespaceConstraint()->namespaces()))
+ error = true;
+ }
+
+ if (error) {
+ m_context->error(QtXmlPatterns::tr("Particle contains non-deterministic wildcards."), XsdSchemaContext::XSDError, sourceLocation(wildcard));
+ return;
+ } else {
+ wildcardMap.insert(wildcard->namespaceConstraint()->variety(), wildcard);
+ }
+ }
+}
+
+QSourceLocation XsdSchemaChecker::sourceLocation(const NamedSchemaComponent::Ptr &component) const
+{
+ if (m_componentLocationHash.contains(component)) {
+ return m_componentLocationHash.value(component);
+ } else {
+ QSourceLocation location;
+ location.setLine(1);
+ location.setColumn(1);
+ location.setUri(QString::fromLatin1("dummyUri"));
+
+ return location;
+ }
+}
+
+QSourceLocation XsdSchemaChecker::sourceLocationForType(const SchemaType::Ptr &type) const
+{
+ if (type->isSimpleType())
+ return sourceLocation(XsdSimpleType::Ptr(type));
+ else
+ return sourceLocation(XsdComplexType::Ptr(type));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp
new file mode 100644
index 0000000..3a44365
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp
@@ -0,0 +1,306 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdSchemaChecker::hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
+{
+ const int length = list.count();
+
+ for (int i = 0; i < length; ++i) {
+ for (int j = 0; j < length; ++j) {
+ if (i == j)
+ continue;
+
+ if (list.at(i)->attribute()->name(m_namePool) == list.at(j)->attribute()->name(m_namePool)) {
+ conflictingAttribute = list.at(i)->attribute();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaChecker::hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const
+{
+ const int length = list.count();
+
+ bool hasIdDerivedAttribute = false;
+ for (int i = 0; i < length; ++i) {
+ if (BuiltinTypes::xsID->wxsTypeMatches(list.at(i)->attribute()->type())) {
+ if (hasIdDerivedAttribute)
+ return true;
+ else
+ hasIdDerivedAttribute = true;
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaChecker::hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
+{
+ const int length = list.count();
+
+ for (int i = 0; i < length; ++i) {
+ const XsdAttributeUse::Ptr attributeUse(list.at(i));
+ if (BuiltinTypes::xsID->wxsTypeMatches(attributeUse->attribute()->type())) {
+ if (attributeUse->valueConstraint()) {
+ conflictingAttribute = attributeUse->attribute();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaChecker::particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
+ //TODO: find out what 'properties' of a particle should be checked here...
+
+ if (particle->minimumOccurs() != otherParticle->minimumOccurs())
+ return false;
+
+ if (particle->maximumOccursUnbounded() != otherParticle->maximumOccursUnbounded())
+ return false;
+
+ if (particle->maximumOccurs() != otherParticle->maximumOccurs())
+ return false;
+
+ const XsdTerm::Ptr term = particle->term();
+ const XsdTerm::Ptr otherTerm = otherParticle->term();
+
+ if (term->isElement() && !(otherTerm->isElement()))
+ return false;
+
+ if (term->isModelGroup() && !(otherTerm->isModelGroup()))
+ return false;
+
+ if (term->isWildcard() && !(otherTerm->isWildcard()))
+ return false;
+
+ if (term->isElement()) {
+ const XsdElement::Ptr element = term;
+ const XsdElement::Ptr otherElement = otherTerm;
+
+ if (element->name(m_namePool) != otherElement->name(m_namePool))
+ return false;
+
+ if (element->type()->name(m_namePool) != otherElement->type()->name(m_namePool))
+ return false;
+ }
+
+ if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group = term;
+ const XsdModelGroup::Ptr otherGroup = otherTerm;
+
+ if (group->particles().count() != otherGroup->particles().count())
+ return false;
+
+ for (int i = 0; i < group->particles().count(); ++i) {
+ if (!particleEqualsRecursively(group->particles().at(i), otherGroup->particles().at(i)))
+ return false;
+ }
+ }
+
+ if (term->isWildcard()) {
+ }
+
+ return true;
+}
+
+bool XsdSchemaChecker::isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
+
+ // 1
+ if (extension == base)
+ return true;
+
+ // 2
+ if (extension->minimumOccurs() == 1 && extension->maximumOccurs() == 1 && extension->maximumOccursUnbounded() == false) {
+ if (extension->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr modelGroup = extension->term();
+ if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) {
+ if (particleEqualsRecursively(modelGroup->particles().first(), base))
+ return true;
+ }
+ }
+ }
+
+ // 3
+ if (extension->minimumOccurs() == base->minimumOccurs()) { // 3.1
+ if (extension->term()->isModelGroup() && base->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr extensionGroup(extension->term());
+ const XsdModelGroup::Ptr baseGroup(base->term());
+
+ if (extensionGroup->compositor() == XsdModelGroup::AllCompositor && baseGroup->compositor() == XsdModelGroup::AllCompositor) {
+ const XsdParticle::List extensionParticles = extensionGroup->particles();
+ const XsdParticle::List baseParticles = baseGroup->particles();
+ for (int i = 0; i < baseParticles.count() && i < extensionParticles.count(); ++i) {
+ if (baseParticles.at(i) != extensionParticles.at(i))
+ return false;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+QSet<XsdElement::Ptr> collectAllElements(const XsdParticle::Ptr &particle)
+{
+ QSet<XsdElement::Ptr> elements;
+
+ const XsdTerm::Ptr term(particle->term());
+ if (term->isElement()) {
+ elements.insert(XsdElement::Ptr(term));
+ } else if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group(term);
+
+ for (int i = 0; i < group->particles().count(); ++i)
+ elements.unite(collectAllElements(group->particles().at(i)));
+ }
+
+ return elements;
+}
+
+QSet<XsdElement::Ptr> collectAllElements(const XsdSchema::Ptr &schema)
+{
+ QSet<XsdElement::Ptr> elements;
+
+ // collect global elements
+ const XsdElement::List elementList = schema->elements();
+ for (int i = 0; i < elementList.count(); ++i)
+ elements.insert(elementList.at(i));
+
+ // collect all elements from global groups
+ const XsdModelGroup::List groupList = schema->elementGroups();
+ for (int i = 0; i < groupList.count(); ++i) {
+ const XsdModelGroup::Ptr group(groupList.at(i));
+
+ for (int j = 0; j < group->particles().count(); ++j)
+ elements.unite(collectAllElements(group->particles().at(j)));
+ }
+
+ // collect all elements from complex type definitions
+ SchemaType::List types;
+ types << schema->types() << schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(types.at(i));
+ if (complexType->contentType()->particle())
+ elements.unite(collectAllElements(complexType->contentType()->particle()));
+ }
+ }
+
+ return elements;
+}
+
+bool XsdSchemaChecker::elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-accept
+
+ if (particle->term()->isWildcard()) { // 1
+ const XsdWildcard::Ptr wildcard(particle->term());
+
+ // 1.1
+ if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
+ return false;
+
+ // 1.2
+ if (!particle->maximumOccursUnbounded()) {
+ if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
+ return false;
+ }
+
+ // 1.3
+ const XsdParticle::List particles(sequence->particles());
+ for (int i = 0; i < particles.count(); ++i) {
+ if (particles.at(i)->term()->isElement()) {
+ if (!XsdSchemaHelper::wildcardAllowsExpandedName(XsdElement::Ptr(particles.at(i)->term())->name(m_namePool), wildcard, m_namePool))
+ return false;
+ }
+ }
+ } else if (particle->term()->isElement()) { // 2
+ const XsdElement::Ptr element(particle->term());
+
+ // 2.1
+ if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
+ return false;
+
+ // 2.2
+ if (!particle->maximumOccursUnbounded()) {
+ if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
+ return false;
+ }
+
+ // 2.3
+ const XsdParticle::List particles(sequence->particles());
+ for (int i = 0; i < particles.count(); ++i) {
+ bool isValid = false;
+ if (particles.at(i)->term()->isElement()) {
+ const XsdElement::Ptr seqElement(particles.at(i)->term());
+
+ // 2.3.1
+ if (element->name(m_namePool) == seqElement->name(m_namePool))
+ isValid = true;
+
+ // 2.3.2
+ if (element->scope() && element->scope()->variety() == XsdElement::Scope::Global) {
+ if (!(element->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint)) {
+ //TODO: continue
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemachecker_p.h b/src/xmlpatterns/schema/qxsdschemachecker_p.h
new file mode 100644
index 0000000..b4966d9
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker_p.h
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaChecker_H
+#define Patternist_XsdSchemaChecker_H
+
+#include "qschematype_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdsimpletype_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class XsdSchemaContext;
+ class XsdSchemaParserContext;
+
+ /**
+ * @short Encapsulates the checking of schema valitity after reference resolving has finished.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaChecker : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchemaChecker> Ptr;
+
+ /**
+ * Creates a new schema checker.
+ *
+ * @param context The context that is used for customization.
+ * @param parserContext The context that contains all the data structures.
+ */
+ XsdSchemaChecker(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext);
+
+ /**
+ * Destroys the schema checker.
+ */
+ ~XsdSchemaChecker();
+
+ /**
+ * Starts a basic check process.
+ *
+ * This check only validates the basic super type inheritance
+ * of simple and complex types.
+ */
+ void basicCheck();
+
+ /**
+ * Starts the real check process.
+ */
+ void check();
+
+ /**
+ * Checks the constraining facets of all global and anonymous simple types for validity.
+ */
+ void checkConstrainingFacets();
+
+ /**
+ * Adds the component location hash, so the checker is able to report meaning full
+ * error messages.
+ */
+ void addComponentLocationHash(const QHash<NamedSchemaComponent::Ptr, QSourceLocation> &hash);
+
+ private:
+ void checkSimpleRestrictionBaseType();
+
+ /**
+ * Checks that no simple or complex type inherits itself.
+ */
+ void checkBasicCircularInheritances();
+
+ /**
+ * Checks the advanced circular inheritance.
+ */
+ void checkCircularInheritances();
+
+ /**
+ * Checks for inheritance restrictions given by final or finalDefault
+ * attributes.
+ */
+ void checkInheritanceRestrictions();
+
+ /**
+ * Checks for various constraints for simple types defined by schema.
+ */
+ void checkBasicSimpleTypeConstraints();
+ void checkSimpleTypeConstraints();
+
+ /**
+ * Checks for various constraints for complex types defined by schema.
+ */
+ void checkBasicComplexTypeConstraints();
+ void checkComplexTypeConstraints();
+
+ /**
+ * Checks for list and union derivation restrictions given by final or finalDefault
+ * attributes.
+ */
+ void checkSimpleDerivationRestrictions();
+
+ /**
+ * Checks the set of constraining @p facets that belongs to @p simpleType for validity.
+ */
+ void checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType);
+
+ /**
+ * Checks for duplicated attribute uses (attributes with the same name) inside a complex type.
+ */
+ void checkDuplicatedAttributeUses();
+
+ /**
+ * Check the element constraints.
+ */
+ void checkElementConstraints();
+
+ /**
+ * Check the attribute constraints.
+ */
+ void checkAttributeConstraints();
+
+ /**
+ * Check the attribute use constraints.
+ */
+ void checkAttributeUseConstraints();
+
+ /**
+ * A map used to find duplicated elements inside a model group.
+ */
+ typedef QHash<QXmlName, SchemaType::Ptr> DuplicatedElementMap;
+
+ /**
+ * A map used to find duplicated wildcards inside a model group.
+ */
+ typedef QHash<XsdWildcard::NamespaceConstraint::Variety, XsdWildcard::Ptr> DuplicatedWildcardMap;
+
+ /**
+ * Check for duplicated elements and element wildcards in all complex type particles.
+ */
+ void checkElementDuplicates();
+
+ /**
+ * Check for duplicated elements and element wildcards in the given @p particle.
+ *
+ * @param particle The particle to check.
+ * @param elementMap A map to find the duplicated elements.
+ * @param wildcardMap A map to find the duplicated element wildcards.
+ */
+ void checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap);
+
+ /**
+ * Setup fast lookup list for allowed facets of atomic simple types.
+ */
+ void setupAllowedAtomicFacets();
+
+ /**
+ * Returns the source location of the given schema @p component or a dummy
+ * source location if the component is not found in the component location hash.
+ */
+ QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const;
+
+ /**
+ * Returns the source location of the given schema @p type or a dummy
+ * source location if the type is not found in the component location hash.
+ */
+ QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const;
+
+ /**
+ * Checks that the string @p value is valid according the value space of @p type
+ * for the given @p component.
+ */
+ bool isValidValue(const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+
+ /**
+ * Returns the list of facets for the given @p type.
+ */
+ XsdFacet::Hash facetsForType(const SchemaType::Ptr &type) const;
+
+ /**
+ * Returns whether the given @p list of attribute uses contains two (or more) attribute
+ * uses that point to attributes with the same name. @p conflictingAttribute
+ * will contain the conflicting attribute in that case.
+ */
+ bool hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const;
+
+ /**
+ * Returns whether the given @p list of attribute uses contains two (or more) attribute
+ * uses that have a type inherited by xs:ID.
+ */
+ bool hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const;
+
+ /**
+ * Returns whether the given @p list of attribute uses contains an attribute
+ * uses that has a type inherited by xs:ID with a value constraint. @p conflictingAttribute
+ * will contain the conflicting attribute in that case.
+ */
+ bool hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const;
+
+ /**
+ * Checks whether the @p particle equals the @p otherParticle recursively.
+ */
+ bool particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const;
+
+ /**
+ * Checks whether the @p extension particle is a valid extension of the @p base particle.
+ */
+ bool isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const;
+
+ /**
+ * Checks whether the @p sequence of elements is accepted by the given @p particle.
+ */
+ bool elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const;
+
+ QExplicitlySharedDataPointer<XsdSchemaContext> m_context;
+ NamePool::Ptr m_namePool;
+ XsdSchema::Ptr m_schema;
+ QHash<QXmlName, QSet<XsdFacet::Type> > m_allowedAtomicFacets;
+ QHash<NamedSchemaComponent::Ptr, QSourceLocation> m_componentLocationHash;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp b/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp
new file mode 100644
index 0000000..2d08e11
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp
@@ -0,0 +1,327 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemachecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdSchemaChecker::setupAllowedAtomicFacets()
+{
+ // string
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsString->name(m_namePool), facets);
+ }
+
+ // boolean
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsBoolean->name(m_namePool), facets);
+ }
+
+ // float
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsFloat->name(m_namePool), facets);
+ }
+
+ // double
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDouble->name(m_namePool), facets);
+ }
+
+ // decimal
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::TotalDigits
+ << XsdFacet::FractionDigits
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDecimal->name(m_namePool), facets);
+ }
+
+ // duration
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDuration->name(m_namePool), facets);
+ }
+
+ // dateTime
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDateTime->name(m_namePool), facets);
+ }
+
+ // time
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsTime->name(m_namePool), facets);
+ }
+
+ // date
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDate->name(m_namePool), facets);
+ }
+
+ // gYearMonth
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGYearMonth->name(m_namePool), facets);
+ }
+
+ // gYear
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGYear->name(m_namePool), facets);
+ }
+
+ // gMonthDay
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGMonthDay->name(m_namePool), facets);
+ }
+
+ // gDay
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGDay->name(m_namePool), facets);
+ }
+
+ // gMonth
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGMonth->name(m_namePool), facets);
+ }
+
+ // hexBinary
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsHexBinary->name(m_namePool), facets);
+ }
+
+ // base64Binary
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsBase64Binary->name(m_namePool), facets);
+ }
+
+ // anyURI
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsAnyURI->name(m_namePool), facets);
+ }
+
+ // QName
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsQName->name(m_namePool), facets);
+ }
+
+ // NOTATION
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsNOTATION->name(m_namePool), facets);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp
new file mode 100644
index 0000000..8e22632
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp
@@ -0,0 +1,528 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemacontext_p.h"
+
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qxsdschematypesfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaContext::XsdSchemaContext(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+ , m_networkAccessManager(0)
+ , m_uriResolver(0)
+ , m_messageHandler(0)
+{
+}
+
+NamePool::Ptr XsdSchemaContext::namePool() const
+{
+ return m_namePool;
+}
+
+QUrl XsdSchemaContext::baseURI() const
+{
+ return m_baseURI;
+}
+
+void XsdSchemaContext::setBaseURI(const QUrl &uri)
+{
+ m_baseURI = uri;
+}
+
+void XsdSchemaContext::setNetworkAccessManager(QNetworkAccessManager *accessManager)
+{
+ m_networkAccessManager = accessManager;
+}
+
+QNetworkAccessManager* XsdSchemaContext::networkAccessManager() const
+{
+ return m_networkAccessManager;
+}
+
+void XsdSchemaContext::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ m_messageHandler = handler;
+}
+
+QAbstractMessageHandler* XsdSchemaContext::messageHandler() const
+{
+ return m_messageHandler;
+}
+
+QSourceLocation XsdSchemaContext::locationFor(const SourceLocationReflection *const) const
+{
+ return QSourceLocation();
+}
+
+void XsdSchemaContext::setUriResolver(const QAbstractUriResolver *uriResolver)
+{
+ m_uriResolver = uriResolver;
+}
+
+const QAbstractUriResolver* XsdSchemaContext::uriResolver() const
+{
+ return m_uriResolver;
+}
+
+XsdFacet::Hash XsdSchemaContext::facetsForType(const AnySimpleType::Ptr &type) const
+{
+ if (type->isDefinedBySchema())
+ return XsdSimpleType::Ptr(type)->facets();
+ else {
+ if (m_builtinTypesFacetList.isEmpty())
+ m_builtinTypesFacetList = setupBuiltinTypesFacetList();
+
+ return m_builtinTypesFacetList.value(type);
+ }
+}
+
+SchemaTypeFactory::Ptr XsdSchemaContext::schemaTypeFactory() const
+{
+ if (!m_schemaTypeFactory)
+ m_schemaTypeFactory = SchemaTypeFactory::Ptr(new XsdSchemaTypesFactory(m_namePool));
+
+ return m_schemaTypeFactory;
+}
+
+QHash<SchemaType::Ptr, XsdFacet::Hash> XsdSchemaContext::setupBuiltinTypesFacetList() const
+{
+ QHash<SchemaType::Ptr, XsdFacet::Hash> hash;
+
+ const XsdFacet::Ptr fixedCollapseWhiteSpace(new XsdFacet());
+ fixedCollapseWhiteSpace->setType(XsdFacet::WhiteSpace);
+ fixedCollapseWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+ fixedCollapseWhiteSpace->setFixed(true);
+
+ const XsdFacet::Ptr collapseWhiteSpace(new XsdFacet());
+ collapseWhiteSpace->setType(XsdFacet::WhiteSpace);
+ collapseWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+ collapseWhiteSpace->setFixed(false);
+
+ const XsdFacet::Ptr preserveWhiteSpace(new XsdFacet());
+ preserveWhiteSpace->setType(XsdFacet::WhiteSpace);
+ preserveWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Preserve)));
+ preserveWhiteSpace->setFixed(false);
+
+ const XsdFacet::Ptr replaceWhiteSpace(new XsdFacet());
+ replaceWhiteSpace->setType(XsdFacet::WhiteSpace);
+ replaceWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Replace)));
+ replaceWhiteSpace->setFixed(false);
+
+ const XsdFacet::Ptr fixedZeroFractionDigits(new XsdFacet());
+ fixedZeroFractionDigits->setType(XsdFacet::FractionDigits);
+ fixedZeroFractionDigits->setValue(DerivedInteger<TypeNonNegativeInteger>::fromValue(m_namePool, 0));
+ fixedZeroFractionDigits->setFixed(true);
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsString];
+ facets.insert(preserveWhiteSpace->type(), preserveWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsBoolean];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDecimal];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsFloat];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDouble];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDuration];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDateTime];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsTime];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDate];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGYearMonth];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGYear];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGMonthDay];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGDay];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGMonth];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsHexBinary];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsBase64Binary];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsAnyURI];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsQName];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNOTATION];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNormalizedString];
+ facets.insert(replaceWhiteSpace->type(), replaceWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsToken];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsLanguage];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNMTOKEN];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("\\c+")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsName];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("\\i\\c*")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ const XsdFacet::Ptr ncNamePattern(new XsdFacet());
+ {
+ ncNamePattern->setType(XsdFacet::Pattern);
+ AtomicValue::List patterns;
+ patterns << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("\\i\\c*"));
+ patterns << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[\\i-[:]][\\c-[:]]*"));
+ ncNamePattern->setMultiValue(patterns);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNCName];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsID];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsIDREF];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsENTITY];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ const XsdFacet::Ptr integerPattern(new XsdFacet());
+ integerPattern->setType(XsdFacet::Pattern);
+ integerPattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[\\-+]?[0-9]+")));
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNonPositiveInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("0")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNegativeInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-1")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsLong];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("9223372036854775807")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-9223372036854775808")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsInt];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("2147483647")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-2147483648")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsShort];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("32767")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-32768")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsByte];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("127")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-128")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ const XsdFacet::Ptr unsignedMinInclusive(new XsdFacet());
+ unsignedMinInclusive->setType(XsdFacet::MinimumInclusive);
+ unsignedMinInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("0")));
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNonNegativeInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedLong];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("18446744073709551615")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedInt];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("4294967295")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedShort];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("65535")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedByte];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("255")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsPositiveInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("1")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsYearMonthDuration];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[^DT]*")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDayTimeDuration];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[^YM]*(T.*)?")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ return hash;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h
new file mode 100644
index 0000000..6a04ba3
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaContext_H
+#define Patternist_XsdSchemaContext_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qreportcontext_p.h"
+#include "qschematypefactory_p.h"
+#include "qxsdschematoken_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdschemachecker_p.h"
+#include "qxsdschemaresolver_p.h"
+
+#include <QtCore/QUrl>
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtXmlPatterns/QAbstractMessageHandler>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A context for schema parsing and validation.
+ *
+ * This class provides the infrastructure for error reporting and
+ * network access. Additionally it stores objects that are used by
+ * both, the parser and the validator.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaContext : public ReportContext
+ {
+ public:
+ /**
+ * A smart pointer wrapping XsdSchemaContext instances.
+ */
+ typedef QExplicitlySharedDataPointer<XsdSchemaContext> Ptr;
+
+ /**
+ * Creates a new schema context object.
+ *
+ * @param namePool The name pool all names belong to.
+ */
+ XsdSchemaContext(const NamePool::Ptr &namePool);
+
+ /**
+ * Returns the name pool of the schema context.
+ */
+ virtual NamePool::Ptr namePool() const;
+
+ /**
+ * Sets the base URI for the main schema.
+ *
+ * The main schema is the one that includes resp. imports
+ * all the other schema files.
+ */
+ virtual void setBaseURI(const QUrl &uri);
+
+ /**
+ * Returns the base URI of the main schema.
+ */
+ virtual QUrl baseURI() const;
+
+ /**
+ * Sets the network access manager that should be used
+ * to access referenced schema definitions.
+ */
+ void setNetworkAccessManager(QNetworkAccessManager *accessManager);
+
+ /**
+ * Returns the network access manager that is used to
+ * access referenced schema definitions.
+ */
+ virtual QNetworkAccessManager* networkAccessManager() const;
+
+ /**
+ * Sets the message @p handler used by the context for error reporting.
+ */
+ void setMessageHandler(QAbstractMessageHandler *handler);
+
+ /**
+ * Returns the message handler used by the context for
+ * error reporting.
+ */
+ virtual QAbstractMessageHandler* messageHandler() const;
+
+ /**
+ * Always returns an empty source location.
+ */
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Sets the uri @p resolver that is used for resolving URIs in the
+ * schema parser.
+ */
+ void setUriResolver(const QAbstractUriResolver *resolver);
+
+ /**
+ * Returns the uri resolver that is used for resolving URIs in the
+ * schema parser.
+ */
+ virtual const QAbstractUriResolver* uriResolver() const;
+
+ /**
+ * Returns the list of facets for the given simple @p type.
+ */
+ XsdFacet::Hash facetsForType(const AnySimpleType::Ptr &type) const;
+
+ /**
+ * Returns a schema type factory that contains some predefined schema types.
+ */
+ SchemaTypeFactory::Ptr schemaTypeFactory() const;
+
+ /**
+ * The following variables should not be accessed directly.
+ */
+ mutable SchemaTypeFactory::Ptr m_schemaTypeFactory;
+ mutable QHash<SchemaType::Ptr, XsdFacet::Hash> m_builtinTypesFacetList;
+
+ private:
+ QHash<SchemaType::Ptr, XsdFacet::Hash> setupBuiltinTypesFacetList() const;
+
+ NamePool::Ptr m_namePool;
+ QNetworkAccessManager* m_networkAccessManager;
+ QUrl m_baseURI;
+ const QAbstractUriResolver* m_uriResolver;
+ QAbstractMessageHandler* m_messageHandler;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemadebugger.cpp b/src/xmlpatterns/schema/qxsdschemadebugger.cpp
new file mode 100644
index 0000000..8ec7381
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemadebugger.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemadebugger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaDebugger::XsdSchemaDebugger(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+}
+
+void XsdSchemaDebugger::dumpParticle(const XsdParticle::Ptr &particle, int level)
+{
+ QString prefix; prefix.fill(QLatin1Char(' '), level);
+
+ qDebug("%s min=%s max=%s", qPrintable(prefix), qPrintable(QString::number(particle->minimumOccurs())),
+ qPrintable(particle->maximumOccursUnbounded() ? QLatin1String("unbounded") : QString::number(particle->maximumOccurs())));
+
+ if (particle->term()->isElement()) {
+ qDebug("%selement (%s)", qPrintable(prefix), qPrintable(XsdElement::Ptr(particle->term())->displayName(m_namePool)));
+ } else if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ if (group->compositor() == XsdModelGroup::SequenceCompositor) {
+ qDebug("%ssequence", qPrintable(prefix));
+ } else if (group->compositor() == XsdModelGroup::AllCompositor) {
+ qDebug("%sall", qPrintable(prefix));
+ } else if (group->compositor() == XsdModelGroup::ChoiceCompositor) {
+ qDebug("%schoice", qPrintable(prefix));
+ }
+
+ for (int i = 0; i < group->particles().count(); ++i)
+ dumpParticle(group->particles().at(i), level + 5);
+ } else if (particle->term()->isWildcard()) {
+ XsdWildcard::Ptr wildcard(particle->term());
+ qDebug("%swildcard (process=%d)", qPrintable(prefix), wildcard->processContents());
+ }
+}
+
+void XsdSchemaDebugger::dumpInheritance(const SchemaType::Ptr &type, int level)
+{
+ QString prefix; prefix.fill(QLatin1Char(' '), level);
+ qDebug("%s-->%s", qPrintable(prefix), qPrintable(type->displayName(m_namePool)));
+ if (type->wxsSuperType())
+ dumpInheritance(type->wxsSuperType(), ++level);
+}
+
+void XsdSchemaDebugger::dumpWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ QVector<QString> varietyNames;
+ varietyNames.append(QLatin1String("Any"));
+ varietyNames.append(QLatin1String("Enumeration"));
+ varietyNames.append(QLatin1String("Not"));
+
+ QVector<QString> processContentsNames;
+ processContentsNames.append(QLatin1String("Strict"));
+ processContentsNames.append(QLatin1String("Lax"));
+ processContentsNames.append(QLatin1String("Skip"));
+
+ qDebug(" processContents: %s", qPrintable(processContentsNames.at((int)wildcard->processContents())));
+ const XsdWildcard::NamespaceConstraint::Ptr constraint = wildcard->namespaceConstraint();
+ qDebug(" variety: %s", qPrintable(varietyNames.at((int)constraint->variety())));
+ if (constraint->variety() != XsdWildcard::NamespaceConstraint::Any)
+ qDebug() << " namespaces:" << constraint->namespaces();
+}
+
+void XsdSchemaDebugger::dumpType(const SchemaType::Ptr &type)
+{
+ if (type->isComplexType()) {
+ const XsdComplexType::Ptr complexType(type);
+ qDebug("\n+++ Complex Type +++");
+ qDebug("Name: %s (abstract: %s)", qPrintable(complexType->displayName(m_namePool)), complexType->isAbstract() ? "yes" : "no");
+ if (complexType->wxsSuperType())
+ qDebug(" base type: %s", qPrintable(complexType->wxsSuperType()->displayName(m_namePool)));
+ else
+ qDebug(" base type: (none)");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty)
+ qDebug(" content type: empty");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple)
+ qDebug(" content type: simple");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly)
+ qDebug(" content type: element-only");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed)
+ qDebug(" content type: mixed");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (complexType->contentType()->simpleType())
+ qDebug(" simple type: %s", qPrintable(complexType->contentType()->simpleType()->displayName(m_namePool)));
+ else
+ qDebug(" simple type: (none)");
+ }
+
+ const XsdAttributeUse::List uses = complexType->attributeUses();
+ qDebug(" %d attributes", uses.count());
+ for (int i = 0; i < uses.count(); ++i) {
+ qDebug(" attr: %s", qPrintable(uses.at(i)->attribute()->displayName(m_namePool)));
+ }
+ qDebug(" has attribute wildcard: %s", complexType->attributeWildcard() ? "yes" : "no");
+ if (complexType->attributeWildcard()) {
+ dumpWildcard(complexType->attributeWildcard());
+ }
+
+ if (complexType->contentType()->particle()) {
+ dumpParticle(complexType->contentType()->particle(), 5);
+ }
+ } else {
+ qDebug("\n+++ Simple Type +++");
+ qDebug("Name: %s", qPrintable(type->displayName(m_namePool)));
+ if (type->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleType(type);
+ if (simpleType->primitiveType())
+ qDebug(" primitive type: %s", qPrintable(simpleType->primitiveType()->displayName(m_namePool)));
+ else
+ qDebug(" primitive type: (none)");
+ }
+ dumpInheritance(type, 0);
+ }
+}
+
+
+void XsdSchemaDebugger::dumpElement(const XsdElement::Ptr &element)
+{
+ QStringList disallowedSubstGroup;
+ if (element->disallowedSubstitutions() & XsdElement::RestrictionConstraint)
+ disallowedSubstGroup << QLatin1String("restriction");
+ if (element->disallowedSubstitutions() & XsdElement::ExtensionConstraint)
+ disallowedSubstGroup << QLatin1String("extension");
+ if (element->disallowedSubstitutions() & XsdElement::SubstitutionConstraint)
+ disallowedSubstGroup << QLatin1String("substitution");
+
+
+ qDebug() << "Name:" << element->displayName(m_namePool);
+ qDebug() << "IsAbstract:" << (element->isAbstract() ? "yes" : "no");
+ qDebug() << "Type:" << element->type()->displayName(m_namePool);
+ qDebug() << "DisallowedSubstitutionGroups:" << disallowedSubstGroup.join(QLatin1String("' "));
+}
+
+void XsdSchemaDebugger::dumpAttribute(const XsdAttribute::Ptr &attribute)
+{
+ qDebug() << "Name:" << attribute->displayName(m_namePool);
+ qDebug() << "Type:" << attribute->type()->displayName(m_namePool);
+}
+
+void XsdSchemaDebugger::dumpSchema(const XsdSchema::Ptr &schema)
+{
+ qDebug() << "------------------------------ Schema -------------------------------";
+
+ // elements
+ {
+ qDebug() << "Global Elements:";
+ const XsdElement::List elements = schema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ dumpElement(elements.at(i));
+ }
+ }
+
+ // attributes
+ {
+ qDebug() << "Global Attributes:";
+ const XsdAttribute::List attributes = schema->attributes();
+ for (int i = 0; i < attributes.count(); ++i) {
+ dumpAttribute(attributes.at(i));
+ }
+ }
+
+ // types
+ {
+ qDebug() << "Global Types:";
+ const SchemaType::List types = schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ dumpType(types.at(i));
+ }
+ }
+
+ // anonymous types
+ {
+ qDebug() << "Anonymous Types:";
+ const SchemaType::List types = schema->anonymousTypes();
+ for (int i = 0; i < types.count(); ++i) {
+ dumpType(types.at(i));
+ }
+ }
+
+ qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h
new file mode 100644
index 0000000..2225b88
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaDebugger_H
+#define Patternist_XsdSchemaDebugger_H
+
+#include "qxsdschema_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * A helper class to print out the structure of a compiled schema.
+ */
+ class XsdSchemaDebugger
+ {
+ public:
+ /**
+ * Creates a new schema debugger.
+ *
+ * @param namePool The name pool that the schema uses.
+ */
+ XsdSchemaDebugger(const NamePool::Ptr &namePool);
+
+ /**
+ * Dumps the structure of the given @p particle.
+ *
+ * @param particle The particle to dump.
+ * @param level The level of indention.
+ */
+ void dumpParticle(const XsdParticle::Ptr &particle, int level = 0);
+
+ /**
+ * Dumps the inheritance path of the given @p type.
+ *
+ * @param type The type to dump.
+ * @param level The level of indention.
+ */
+ void dumpInheritance(const SchemaType::Ptr &type, int level = 0);
+
+ /**
+ * Dumps the structure of the given @p wildcard.
+ */
+ void dumpWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Dumps the structure of the given @p type.
+ */
+ void dumpType(const SchemaType::Ptr &type);
+
+ /**
+ * Dumps the structure of the given @p element.
+ */
+ void dumpElement(const XsdElement::Ptr &element);
+
+ /**
+ * Dumps the structure of the given @p attribute.
+ */
+ void dumpAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Dumps the structure of the complete @p schema.
+ */
+ void dumpSchema(const XsdSchema::Ptr &schema);
+
+ private:
+ const NamePool::Ptr m_namePool;
+ };
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp
new file mode 100644
index 0000000..7813808
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp
@@ -0,0 +1,821 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemahelper_p.h"
+
+#include "qbuiltintypes_p.h"
+#include "qvaluefactory_p.h"
+#include "qxsdcomplextype_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdsimpletype_p.h"
+#include "qxsdtypechecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/*
+ * Calculates the effective total range minimum of the given @p particle as
+ * described by the algorithm in the schema spec.
+ */
+static inline unsigned int effectiveTotalRangeMinimum(const XsdParticle::Ptr &particle)
+{
+ const XsdModelGroup::Ptr group = particle->term();
+
+ if (group->compositor() == XsdModelGroup::ChoiceCompositor) {
+ // @see http://www.w3.org/TR/xmlschema11-1/# cos-choice-range
+
+ int minValue = -1;
+
+ const XsdParticle::List particles = group->particles();
+ if (particles.isEmpty())
+ minValue = 0;
+
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdParticle::Ptr particle = particles.at(i);
+
+ if (particle->term()->isElement() || particle->term()->isWildcard()) {
+ if (minValue == -1) {
+ minValue = particle->minimumOccurs();
+ } else {
+ minValue = qMin((unsigned int)minValue, particle->minimumOccurs());
+ }
+ } else if (particle->term()->isModelGroup()) {
+ if (minValue == -1) {
+ minValue = effectiveTotalRangeMinimum(particle);
+ } else {
+ minValue = qMin((unsigned int)minValue, effectiveTotalRangeMinimum(particle));
+ }
+ }
+ }
+
+ return (particle->minimumOccurs() * minValue);
+
+ } else {
+ // @see http://www.w3.org/TR/xmlschema11-1/# cos-seq-range
+
+ unsigned int sum = 0;
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdParticle::Ptr particle = particles.at(i);
+
+ if (particle->term()->isElement() || particle->term()->isWildcard())
+ sum += particle->minimumOccurs();
+ else if (particle->term()->isModelGroup())
+ sum += effectiveTotalRangeMinimum(particle);
+ }
+
+ return (particle->minimumOccurs() * sum);
+ }
+}
+
+bool XsdSchemaHelper::isParticleEmptiable(const XsdParticle::Ptr &particle)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-group-emptiable
+
+ if (particle->minimumOccurs() == 0)
+ return true;
+
+ if (!(particle->term()->isModelGroup()))
+ return false;
+
+ return (effectiveTotalRangeMinimum(particle) == 0);
+}
+
+bool XsdSchemaHelper::wildcardAllowsNamespaceName(const QString &nameSpace, const XsdWildcard::NamespaceConstraint::Ptr &constraint)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard-namespace
+
+ // 1
+ if (constraint->variety() == XsdWildcard::NamespaceConstraint::Any)
+ return true;
+
+ // 2
+ if (constraint->variety() == XsdWildcard::NamespaceConstraint::Not) { // 2.1
+ if (!constraint->namespaces().contains(nameSpace)) // 2.2
+ if (nameSpace != XsdWildcard::absentNamespace()) // 2.3
+ return true;
+ }
+
+ // 3
+ if (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) {
+ if (constraint->namespaces().contains(nameSpace))
+ return true;
+ }
+
+ return false;
+}
+
+bool XsdSchemaHelper::wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard-name
+
+ // 1
+ if (!wildcardAllowsNamespaceName(namePool->stringForNamespace(name.namespaceURI()), wildcard->namespaceConstraint()))
+ return false;
+
+ // 2, 3, 4
+ //TODO: we have no disallowed namespace yet
+
+ return true;
+}
+
+// small helper function that should be available in Qt 4.6
+template<class T>
+static inline bool containsSet(const QSet<T> &super, const QSet<T> &sub)
+{
+ QSetIterator<T> it(sub);
+ while (it.hasNext()) {
+ if (!super.contains(it.next()))
+ return false;
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::isWildcardSubset(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ns-subset
+ // wildcard =^ sub
+ // otherWildcard =^ super
+
+ const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint());
+ const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint());
+
+ // 1
+ if (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)
+ return true;
+
+ // 2
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+ if (containsSet<QString>(otherConstraint->namespaces(), constraint->namespaces()))
+ return true;
+ }
+
+ // 3
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (constraint->namespaces().intersect(otherConstraint->namespaces()).isEmpty())
+ return true;
+ }
+
+ // 4
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (containsSet<QString>(constraint->namespaces(), otherConstraint->namespaces()))
+ return true;
+ }
+
+ return false;
+}
+
+XsdWildcard::Ptr XsdSchemaHelper::wildcardUnion(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-aw-union
+
+ XsdWildcard::Ptr unionWildcard(new XsdWildcard());
+
+ const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint());
+ const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint());
+
+ // 1
+ if ((constraint->variety() == otherConstraint->variety()) &&
+ (constraint->namespaces() == otherConstraint->namespaces())) {
+ unionWildcard->namespaceConstraint()->setVariety(constraint->variety());
+ unionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces());
+ return unionWildcard;
+ }
+
+ // 2
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Any) || (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)) {
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ return unionWildcard;
+ }
+
+ // 3
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ unionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces() + otherConstraint->namespaces());
+ return unionWildcard;
+ }
+
+ // 4
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (constraint->namespaces() != otherConstraint->namespaces()) {
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ return unionWildcard;
+ }
+ }
+
+ // 5
+ QSet<QString> sSet, negatedSet;
+ bool matches5 = false;
+ if (((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && !constraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = constraint->namespaces();
+ sSet = otherConstraint->namespaces();
+ matches5 = true;
+ } else if (((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) && !otherConstraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = otherConstraint->namespaces();
+ sSet = constraint->namespaces();
+ matches5 = true;
+ }
+
+ if (matches5) {
+ if (sSet.contains(negatedSet.values().first()) && sSet.contains(XsdWildcard::absentNamespace())) { // 5.1
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ return unionWildcard;
+ }
+ if (sSet.contains(negatedSet.values().first()) && !sSet.contains(XsdWildcard::absentNamespace())) { // 5.2
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ return unionWildcard;
+ }
+ if (!sSet.contains(negatedSet.values().first()) && sSet.contains(XsdWildcard::absentNamespace())) { // 5.3
+ return XsdWildcard::Ptr(); // not expressible
+ }
+ if (!sSet.contains(negatedSet.values().first()) && !sSet.contains(XsdWildcard::absentNamespace())) { // 5.4
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(negatedSet);
+ return unionWildcard;
+ }
+ }
+
+ // 6
+ bool matches6 = false;
+ if (((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && constraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = constraint->namespaces();
+ sSet = otherConstraint->namespaces();
+ matches6 = true;
+ } else if (((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) && otherConstraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = otherConstraint->namespaces();
+ sSet = constraint->namespaces();
+ matches6 = true;
+ }
+
+ if (matches6) {
+ if (sSet.contains(XsdWildcard::absentNamespace())) { // 6.1
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ return unionWildcard;
+ }
+ if (!sSet.contains(XsdWildcard::absentNamespace())) { // 6.2
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(QSet<QString>() += XsdWildcard::absentNamespace());
+ return unionWildcard;
+ }
+ }
+
+ return XsdWildcard::Ptr();
+}
+
+XsdWildcard::Ptr XsdSchemaHelper::wildcardIntersection(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-aw-intersect
+
+ const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint());
+ const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint());
+
+ const XsdWildcard::Ptr intersectionWildcard(new XsdWildcard());
+
+ // 1
+ if ((constraint->variety() == otherConstraint->variety()) &&
+ (constraint->namespaces() == otherConstraint->namespaces())) {
+ intersectionWildcard->namespaceConstraint()->setVariety(constraint->variety());
+ intersectionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces());
+ return intersectionWildcard;
+ }
+
+ // 2
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Any) &&
+ (otherConstraint->variety() != XsdWildcard::NamespaceConstraint::Any)) {
+ intersectionWildcard->namespaceConstraint()->setVariety(otherConstraint->variety());
+ intersectionWildcard->namespaceConstraint()->setNamespaces(otherConstraint->namespaces());
+ return intersectionWildcard;
+ }
+
+ // 2
+ if ((constraint->variety() != XsdWildcard::NamespaceConstraint::Any) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)) {
+ intersectionWildcard->namespaceConstraint()->setVariety(constraint->variety());
+ intersectionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces());
+ return intersectionWildcard;
+ }
+
+ // 3
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ QSet<QString> set = otherConstraint->namespaces();
+ set.subtract(constraint->namespaces());
+ set.remove(XsdWildcard::absentNamespace());
+
+ intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ intersectionWildcard->namespaceConstraint()->setNamespaces(set);
+
+ return intersectionWildcard;
+ }
+
+ // 3
+ if ((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) &&
+ (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ QSet<QString> set = constraint->namespaces();
+ set.subtract(otherConstraint->namespaces());
+ set.remove(XsdWildcard::absentNamespace());
+
+ intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ intersectionWildcard->namespaceConstraint()->setNamespaces(set);
+
+ return intersectionWildcard;
+ }
+
+ // 4
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ QSet<QString> set = constraint->namespaces();
+ set.intersect(otherConstraint->namespaces());
+
+ intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ intersectionWildcard->namespaceConstraint()->setNamespaces(set);
+
+ return intersectionWildcard;
+ }
+
+ // 6
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (!(constraint->namespaces().contains(XsdWildcard::absentNamespace())) && otherConstraint->namespaces().contains(XsdWildcard::absentNamespace())) {
+ return wildcard;
+ }
+ if (constraint->namespaces().contains(XsdWildcard::absentNamespace()) && !(otherConstraint->namespaces().contains(XsdWildcard::absentNamespace()))) {
+ return otherWildcard;
+ }
+ }
+
+ // 5 as not expressible return empty wildcard
+ return XsdWildcard::Ptr();
+}
+
+static SchemaType::DerivationConstraints convertBlockingConstraints(const NamedSchemaComponent::BlockingConstraints &constraints)
+{
+ SchemaType::DerivationConstraints result = 0;
+
+ if (constraints & NamedSchemaComponent::RestrictionConstraint)
+ result |= SchemaType::RestrictionConstraint;
+ if (constraints & NamedSchemaComponent::ExtensionConstraint)
+ result |= SchemaType::ExtensionConstraint;
+
+ return result;
+}
+
+bool XsdSchemaHelper::isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#key-val-sub-type
+
+ // 1
+ if (type->isComplexType() && otherType->isComplexType()) {
+ SchemaType::DerivationConstraints keywords = constraints;
+ if (otherType->isDefinedBySchema())
+ keywords |= convertBlockingConstraints(XsdComplexType::Ptr(otherType)->prohibitedSubstitutions());
+
+ return isComplexDerivationOk(type, otherType, keywords);
+ }
+
+ // 2
+ if (type->isComplexType() && otherType->isSimpleType()) {
+ return isComplexDerivationOk(type, otherType, constraints);
+ }
+
+ // 3
+ if (type->isSimpleType() && otherType->isSimpleType()) {
+ return isSimpleDerivationOk(type, otherType, constraints);
+ }
+
+ return false;
+}
+
+bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-st-derived-ok
+
+ // 1
+ if (derivedType == baseType)
+ return true;
+
+ // 2.1
+ if ((constraints & SchemaType::RestrictionConstraint) || derivedType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
+ return false;
+ }
+
+ // 2.2.1
+ if (derivedType->wxsSuperType() == baseType)
+ return true;
+
+ // 2.2.2
+ if (derivedType->wxsSuperType() != BuiltinTypes::xsAnyType) {
+ if (isSimpleDerivationOk(derivedType->wxsSuperType(), baseType, constraints))
+ return true;
+ }
+
+ // 2.2.3
+ if (derivedType->category() == SchemaType::SimpleTypeList || derivedType->category() == SchemaType::SimpleTypeUnion) {
+ if (baseType == BuiltinTypes::xsAnySimpleType)
+ return true;
+ }
+
+ // 2.2.4
+ if (baseType->category() == SchemaType::SimpleTypeUnion && baseType->isDefinedBySchema()) { // 2.2.4.1
+ const AnySimpleType::List memberTypes = XsdSimpleType::Ptr(baseType)->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ if (isSimpleDerivationOk(derivedType, memberTypes.at(i), constraints)) { // 2.2.4.2
+ if (XsdSimpleType::Ptr(baseType)->facets().isEmpty()) { // 2.2.4.3
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints)
+{
+ if (!derivedType)
+ return false;
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-derived-ok
+
+ // 1
+ if (derivedType != baseType) {
+ if ((derivedType->derivationMethod() == SchemaType::DerivationRestriction) && (constraints & SchemaType::RestrictionConstraint))
+ return false;
+ if ((derivedType->derivationMethod() == SchemaType::DerivationExtension) && (constraints & SchemaType::ExtensionConstraint))
+ return false;
+ }
+
+ // 2.1
+ if (derivedType == baseType)
+ return true;
+
+ // 2.2
+ if (derivedType->wxsSuperType() == baseType)
+ return true;
+
+ // 2.3
+ bool isOk = true;
+ if (derivedType->wxsSuperType() == BuiltinTypes::xsAnyType) { // 2.3.1
+ isOk = false;
+ } else { // 2.3.2
+ if (!derivedType->wxsSuperType())
+ return false;
+
+ if (derivedType->wxsSuperType()->isComplexType()) { // 2.3.2.1
+ isOk = isComplexDerivationOk(derivedType->wxsSuperType(), baseType, constraints);
+ } else { // 2.3.2.2
+ isOk = isSimpleDerivationOk(derivedType->wxsSuperType(), baseType, constraints);
+ }
+ }
+ if (isOk)
+ return true;
+
+ return false;
+}
+
+bool XsdSchemaHelper::constructAndCompare(const DerivedString<TypeString>::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const DerivedString<TypeString>::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection)
+{
+ Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO,
+ "We can only compare atomic values.");
+
+ // we can not cast a xs:String to a xs:QName, so lets go the safe way
+ if (type->name(context->namePool()) == BuiltinTypes::xsQName->name(context->namePool()))
+ return false;
+
+ const AtomicValue::Ptr value1 = ValueFactory::fromLexical(operand1->stringValue(), type, context, sourceLocationReflection);
+ if (value1->hasError())
+ return false;
+
+ const AtomicValue::Ptr value2 = ValueFactory::fromLexical(operand2->stringValue(), type, context, sourceLocationReflection);
+ if (value2->hasError())
+ return false;
+
+ return ComparisonFactory::compare(value1, op, value2, type, context, sourceLocationReflection);
+}
+
+bool XsdSchemaHelper::checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard)
+{
+ if (baseWildcard->processContents() == XsdWildcard::Strict) {
+ if (derivedWildcard->processContents() == XsdWildcard::Lax || derivedWildcard->processContents() == XsdWildcard::Skip) {
+ return false;
+ }
+ } else if (baseWildcard->processContents() == XsdWildcard::Lax) {
+ if (derivedWildcard->processContents() == XsdWildcard::Skip)
+ return false;
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, QSet<XsdElement::Ptr> &visitedElements)
+{
+ if (visitedElements.contains(member))
+ return false;
+ else
+ visitedElements.insert(member);
+
+ if (member->substitutionGroupAffiliations().isEmpty())
+ return false;
+
+ if (member->substitutionGroupAffiliations().contains(head)) {
+ return true;
+ } else {
+ const XsdElement::List affiliations = member->substitutionGroupAffiliations();
+ for (int i = 0; i < affiliations.count(); ++i) {
+ if (foundSubstitutionGroupTransitive(head, affiliations.at(i), visitedElements))
+ return true;
+ }
+
+ return false;
+ }
+}
+
+void XsdSchemaHelper::foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, const SchemaType::Ptr &memberType,
+ QSet<SchemaType::DerivationMethod> &derivationSet, NamedSchemaComponent::BlockingConstraints &blockSet)
+{
+ if (!memberType)
+ return;
+
+ if (memberType == headType)
+ return;
+
+ derivationSet.insert(memberType->derivationMethod());
+
+ if (memberType->isComplexType()) {
+ const XsdComplexType::Ptr complexType(memberType);
+ blockSet |= complexType->prohibitedSubstitutions();
+ }
+
+ foundSubstitutionGroupTypeInheritance(headType, memberType->wxsSuperType(), derivationSet, blockSet);
+}
+
+bool XsdSchemaHelper::substitutionGroupOkTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, const NamePool::Ptr &namePool)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-equiv-derived-ok-rec
+
+ // 1
+ if ((member->name(namePool) == head->name(namePool)) && (member->type() == head->type()))
+ return true;
+
+ // 2.1
+ if (head->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint)
+ return false;
+
+ // 2.2
+ {
+ QSet<XsdElement::Ptr> visitedElements;
+ if (!foundSubstitutionGroupTransitive(head, member, visitedElements))
+ return false;
+ }
+
+ // 2.3
+ {
+ QSet<SchemaType::DerivationMethod> derivationSet;
+ NamedSchemaComponent::BlockingConstraints blockSet;
+
+ foundSubstitutionGroupTypeInheritance(head->type(), member->type(), derivationSet, blockSet);
+
+ NamedSchemaComponent::BlockingConstraints checkSet(blockSet);
+ checkSet |= head->disallowedSubstitutions();
+ if (head->type()->isComplexType()) {
+ const XsdComplexType::Ptr complexType(head->type());
+ checkSet |= complexType->prohibitedSubstitutions();
+ }
+
+ if ((checkSet & NamedSchemaComponent::RestrictionConstraint) && derivationSet.contains(SchemaType::DerivationRestriction))
+ return false;
+ if ((checkSet & NamedSchemaComponent::ExtensionConstraint) && derivationSet.contains(SchemaType::DerivationExtension))
+ return false;
+ if (checkSet & NamedSchemaComponent::SubstitutionConstraint)
+ return false;
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, const XsdAttributeGroup::Ptr &attributeGroup, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ // @see http://www.w3.org/TR/xmlschema-1/#derivation-ok-restriction
+
+ const XsdAttributeUse::List derivedAttributeUses = derivedAttributeGroup->attributeUses();
+ const XsdAttributeUse::List baseAttributeUses = attributeGroup->attributeUses();
+
+ return isValidAttributeUsesRestriction(derivedAttributeUses, baseAttributeUses,
+ derivedAttributeGroup->wildcard(), attributeGroup->wildcard(), context, errorMsg);
+}
+
+bool XsdSchemaHelper::isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &baseAttributeUses,
+ const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ const NamePool::Ptr namePool(context->namePool());
+
+ QHash<QXmlName, XsdAttributeUse::Ptr> baseAttributeUsesLookup;
+ for (int i = 0; i < baseAttributeUses.count(); ++i)
+ baseAttributeUsesLookup.insert(baseAttributeUses.at(i)->attribute()->name(namePool), baseAttributeUses.at(i));
+
+ QHash<QXmlName, XsdAttributeUse::Ptr> derivedAttributeUsesLookup;
+ for (int i = 0; i < derivedAttributeUses.count(); ++i)
+ derivedAttributeUsesLookup.insert(derivedAttributeUses.at(i)->attribute()->name(namePool), derivedAttributeUses.at(i));
+
+ // 2
+ for (int i = 0; i < derivedAttributeUses.count(); ++i) {
+ const XsdAttributeUse::Ptr derivedAttributeUse = derivedAttributeUses.at(i);
+
+ // prohibited attributes are no real attributes, so skip them in that test here
+ if (derivedAttributeUse->useType() == XsdAttributeUse::ProhibitedUse)
+ continue;
+
+ if (baseAttributeUsesLookup.contains(derivedAttributeUse->attribute()->name(namePool))) {
+ const XsdAttributeUse::Ptr baseAttributeUse(baseAttributeUsesLookup.value(derivedAttributeUse->attribute()->name(namePool)));
+
+ // 2.1.1
+ if (baseAttributeUse->isRequired() == true && derivedAttributeUse->isRequired() == false) {
+ errorMsg = QtXmlPatterns::tr("Base attribute %1 is required but derived attribute is not.").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+
+ // 2.1.2
+ if (!isSimpleDerivationOk(derivedAttributeUse->attribute()->type(), baseAttributeUse->attribute()->type(), SchemaType::DerivationConstraints())) {
+ errorMsg = QtXmlPatterns::tr("Type of derived attribute %1 cannot be validly derived from type of base attribute.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+
+ // 2.1.3
+ XsdAttributeUse::ValueConstraint::Ptr derivedConstraint;
+ if (derivedAttributeUse->valueConstraint())
+ derivedConstraint = derivedAttributeUse->valueConstraint();
+ else if (derivedAttributeUse->attribute()->valueConstraint())
+ derivedConstraint = XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(derivedAttributeUse->attribute()->valueConstraint());
+
+ XsdAttributeUse::ValueConstraint::Ptr baseConstraint;
+ if (baseAttributeUse->valueConstraint())
+ baseConstraint = baseAttributeUse->valueConstraint();
+ else if (baseAttributeUse->attribute()->valueConstraint())
+ baseConstraint = XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(baseAttributeUse->attribute()->valueConstraint());
+
+ bool ok = false;
+ if (!baseConstraint || baseConstraint->variety() == XsdAttributeUse::ValueConstraint::Default)
+ ok = true;
+
+ if (derivedConstraint && baseConstraint) {
+ const XsdTypeChecker checker(context, QVector<QXmlName>(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1));
+ if (derivedConstraint->variety() == XsdAttributeUse::ValueConstraint::Fixed && checker.valuesAreEqual(derivedConstraint->value(), baseConstraint->value(), baseAttributeUse->attribute()->type()))
+ ok = true;
+ }
+
+ if (!ok) {
+ errorMsg = QtXmlPatterns::tr("Value constraint of derived attribute %1 does not match value constraint of base attribute.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ } else {
+ if (!wildcard) {
+ errorMsg = QtXmlPatterns::tr("Derived attribute %1 does not exist in the base definition.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+
+ QXmlName name = derivedAttributeUse->attribute()->name(namePool);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ if (!wildcardAllowsExpandedName(name, wildcard, namePool)) {
+ errorMsg = QtXmlPatterns::tr("Derived attribute %1 does not match the wildcard in the base definition.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ }
+ }
+
+ // 3
+ for (int i = 0; i < baseAttributeUses.count(); ++i) {
+ const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(i);
+
+ if (baseAttributeUse->isRequired()) {
+ if (derivedAttributeUsesLookup.contains(baseAttributeUse->attribute()->name(namePool))) {
+ if (!derivedAttributeUsesLookup.value(baseAttributeUse->attribute()->name(namePool))->isRequired()) {
+ errorMsg = QtXmlPatterns::tr("Base attribute %1 is required but derived attribute is not.").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ } else {
+ errorMsg = QtXmlPatterns::tr("Base attribute %1 is required but missing in derived definition.").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ }
+ }
+
+ // 4
+ if (derivedWildcard) {
+ if (!wildcard) {
+ errorMsg = QtXmlPatterns::tr("Derived definition contains an %1 element that does not exists in the base definition").arg(formatElement("anyAttribute."));
+ return false;
+ }
+
+ if (!isWildcardSubset(derivedWildcard, wildcard)) {
+ errorMsg = QtXmlPatterns::tr("Derived wildcard is not a subset of the base wildcard.");
+ return false;
+ }
+
+ if (!checkWildcardProcessContents(wildcard, derivedWildcard)) {
+ errorMsg = QtXmlPatterns::tr("%1 of derived wildcard is not a valid restriction of %2 of base wildcard").arg(formatKeyword("processContents")).arg(formatKeyword("processContents."));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses,
+ const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends
+
+ const NamePool::Ptr namePool(context->namePool());
+
+ // 1.2
+ QHash<QXmlName, XsdAttribute::Ptr> lookupHash;
+ for (int i = 0; i < derivedAttributeUses.count(); ++i)
+ lookupHash.insert(derivedAttributeUses.at(i)->attribute()->name(namePool), derivedAttributeUses.at(i)->attribute());
+
+ for (int i = 0; i < attributeUses.count(); ++i) {
+ const QXmlName attributeName = attributeUses.at(i)->attribute()->name(namePool);
+ if (!lookupHash.contains(attributeName)) {
+ errorMsg = QtXmlPatterns::tr("Attribute %1 from base type is missing in derived type.").arg(formatKeyword(namePool->displayName(attributeName)));
+ return false;
+ }
+
+ if (lookupHash.value(attributeName)->type() != attributeUses.at(i)->attribute()->type()) {
+ errorMsg = QtXmlPatterns::tr("Type of derived attribute %1 differs from type of base attribute.").arg(formatKeyword(namePool->displayName(attributeName)));
+ return false;
+ }
+ }
+
+ // 1.3
+ if (wildcard) {
+ if (!derivedWildcard) {
+ errorMsg = QtXmlPatterns::tr("Base definition contains an %1 element that is missing in the derived definition").arg(formatElement("anyAttribute."));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h
new file mode 100644
index 0000000..410b224
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaHelper_H
+#define Patternist_XsdSchemaHelper_H
+
+#include "qcomparisonfactory_p.h"
+#include "qschematype_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdparticle_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdwildcard_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Contains helper methods that are used by XsdSchemaParser, XsdSchemaResolver and XsdSchemaChecker.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaHelper
+ {
+ public:
+ /**
+ * Checks whether the given @p particle is emptiable as defined by the
+ * algorithm in the schema spec.
+ */
+ static bool isParticleEmptiable(const XsdParticle::Ptr &particle);
+
+ /**
+ * Checks whether the given @p nameSpace is allowed by the given namespace @p constraint.
+ */
+ static bool wildcardAllowsNamespaceName(const QString &nameSpace,
+ const XsdWildcard::NamespaceConstraint::Ptr &constraint);
+
+ /**
+ * Checks whether the given @p name is allowed by the namespace constraint of the given @p wildcard.
+ */
+ static bool wildcardAllowsExpandedName(const QXmlName &name,
+ const XsdWildcard::Ptr &wildcard,
+ const NamePool::Ptr &namePool);
+
+ /**
+ * Checks whether the @p wildcard is a subset of @p otherWildcard.
+ */
+ static bool isWildcardSubset(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard);
+
+ /**
+ * Returns the union of the given @p wildcard and @p otherWildcard.
+ */
+ static XsdWildcard::Ptr wildcardUnion(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard);
+
+ /**
+ * Returns the intersection of the given @p wildcard and @p otherWildcard.
+ */
+ static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard,
+ const XsdWildcard::Ptr &otherWildcard);
+
+ /**
+ * Returns whether the given @p type is validly substitutable for an @p otherType
+ * under the given @p constraints.
+ */
+ static bool isValidlySubstitutable(const SchemaType::Ptr &type,
+ const SchemaType::Ptr &otherType,
+ const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * Returns whether the simple @p derivedType can be derived from the simple @p baseType
+ * under the given @p constraints.
+ */
+ static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType,
+ const SchemaType::Ptr &baseType,
+ const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * Returns whether the complex @p derivedType can be derived from the complex @p baseType
+ * under the given @p constraints.
+ */
+ static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType,
+ const SchemaType::Ptr &baseType,
+ const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * This method takes the two string based operands @p operand1 and @p operand2 and converts them to instances of type @p type.
+ * If the conversion fails, @c false is returned, otherwise the instances are compared by the given operator @p op and the
+ * result of the comparison is returned.
+ */
+ static bool constructAndCompare(const DerivedString<TypeString>::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const DerivedString<TypeString>::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection);
+
+ /**
+ * Returns whether the process content property of the @p derivedWildcard is valid
+ * according to the process content property of its @p baseWildcard.
+ */
+ static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard,
+ const XsdWildcard::Ptr &derivedWildcard);
+
+ /**
+ * Checks whether @[ member is a member of the substitution group with the given @p head.
+ */
+ static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head,
+ const XsdElement::Ptr &member,
+ QSet<XsdElement::Ptr> &visitedElements);
+
+ /**
+ * A helper method that iterates over the type hierarchy from @p memberType up to @p headType and collects all
+ * @p derivationSet and @p blockSet constraints that exists on the way there.
+ */
+ static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType,
+ const SchemaType::Ptr &memberType,
+ QSet<SchemaType::DerivationMethod> &derivationSet,
+ NamedSchemaComponent::BlockingConstraints &blockSet);
+
+ /**
+ * Checks if the @p member is transitive to @p head.
+ */
+ static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head,
+ const XsdElement::Ptr &member,
+ const NamePool::Ptr &namePool);
+
+ /**
+ * Checks if @p derivedAttributeGroup is a valid restriction for @p attributeGroup.
+ */
+ static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup,
+ const XsdAttributeGroup::Ptr &attributeGroup,
+ const XsdSchemaContext::Ptr &context,
+ QString &errorMsg);
+
+ /**
+ * Checks if @p derivedAttributeUses are a valid restriction for @p attributeUses.
+ */
+ static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses,
+ const XsdAttributeUse::List &attributeUses,
+ const XsdWildcard::Ptr &derivedWildcard,
+ const XsdWildcard::Ptr &wildcard,
+ const XsdSchemaContext::Ptr &context,
+ QString &errorMsg);
+
+ /**
+ * Checks if @p derivedAttributeUses are a valid extension for @p attributeUses.
+ */
+ static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses,
+ const XsdAttributeUse::List &attributeUses,
+ const XsdWildcard::Ptr &derivedWildcard,
+ const XsdWildcard::Ptr &wildcard,
+ const XsdSchemaContext::Ptr &context,
+ QString &errorMsg);
+
+ private:
+ Q_DISABLE_COPY(XsdSchemaHelper)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemamerger.cpp b/src/xmlpatterns/schema/qxsdschemamerger.cpp
new file mode 100644
index 0000000..4ffcea3
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemamerger.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemamerger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaMerger::XsdSchemaMerger(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema)
+{
+ merge(schema, otherSchema);
+}
+
+XsdSchema::Ptr XsdSchemaMerger::mergedSchema() const
+{
+ return m_mergedSchema;
+}
+
+void XsdSchemaMerger::merge(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema)
+{
+ m_mergedSchema = XsdSchema::Ptr(new XsdSchema(otherSchema->namePool()));
+
+ // first fill the merged schema with the values from schema
+ if (schema) {
+ const XsdElement::List elements = schema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ m_mergedSchema->addElement(elements.at(i));
+ }
+
+ const XsdAttribute::List attributes = schema->attributes();
+ for (int i = 0; i < attributes.count(); ++i) {
+ m_mergedSchema->addAttribute(attributes.at(i));
+ }
+
+ const SchemaType::List types = schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ m_mergedSchema->addType(types.at(i));
+ }
+
+ const SchemaType::List anonymousTypes = schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ m_mergedSchema->addAnonymousType(anonymousTypes.at(i));
+ }
+
+ const XsdModelGroup::List elementGroups = schema->elementGroups();
+ for (int i = 0; i < elementGroups.count(); ++i) {
+ m_mergedSchema->addElementGroup(elementGroups.at(i));
+ }
+
+ const XsdAttributeGroup::List attributeGroups = schema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ m_mergedSchema->addAttributeGroup(attributeGroups.at(i));
+ }
+
+ const XsdNotation::List notations = schema->notations();
+ for (int i = 0; i < notations.count(); ++i) {
+ m_mergedSchema->addNotation(notations.at(i));
+ }
+
+ const XsdIdentityConstraint::List identityConstraints = schema->identityConstraints();
+ for (int i = 0; i < identityConstraints.count(); ++i) {
+ m_mergedSchema->addIdentityConstraint(identityConstraints.at(i));
+ }
+ }
+
+ // then merge in the values from the otherSchema
+ {
+ const XsdElement::List elements = otherSchema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ if (!m_mergedSchema->element(elements.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addElement(elements.at(i));
+ }
+
+ const XsdAttribute::List attributes = otherSchema->attributes();
+ for (int i = 0; i < attributes.count(); ++i) {
+ if (!m_mergedSchema->attribute(attributes.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addAttribute(attributes.at(i));
+ }
+
+ const SchemaType::List types = otherSchema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!m_mergedSchema->type(types.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addType(types.at(i));
+ }
+
+ const SchemaType::List anonymousTypes = otherSchema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ // add anonymous type as they are
+ m_mergedSchema->addAnonymousType(anonymousTypes.at(i));
+ }
+
+ const XsdModelGroup::List elementGroups = otherSchema->elementGroups();
+ for (int i = 0; i < elementGroups.count(); ++i) {
+ if (!m_mergedSchema->elementGroup(elementGroups.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addElementGroup(elementGroups.at(i));
+ }
+
+ const XsdAttributeGroup::List attributeGroups = otherSchema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ if (!m_mergedSchema->attributeGroup(attributeGroups.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addAttributeGroup(attributeGroups.at(i));
+ }
+
+ const XsdNotation::List notations = otherSchema->notations();
+ for (int i = 0; i < notations.count(); ++i) {
+ if (!m_mergedSchema->notation(notations.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addNotation(notations.at(i));
+ }
+
+ const XsdIdentityConstraint::List identityConstraints = otherSchema->identityConstraints();
+ for (int i = 0; i < identityConstraints.count(); ++i) {
+ if (!m_mergedSchema->identityConstraint(identityConstraints.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addIdentityConstraint(identityConstraints.at(i));
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemamerger_p.h b/src/xmlpatterns/schema/qxsdschemamerger_p.h
new file mode 100644
index 0000000..599a08b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemamerger_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaMerger_H
+#define Patternist_XsdSchemaMerger_H
+
+#include "qxsdschema_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class that merges two schemas into one.
+ *
+ * This class is used in XsdValidatingInstanceReader to merge the schema
+ * given in the constructor with a schema defined in the instance document
+ * via xsi:schemaLocation or xsi:noNamespaceSchema location.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaMerger : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchemaMerger> Ptr;
+
+ /**
+ * Creates a new schema merger object that merges @p schema with @p otherSchema.
+ */
+ XsdSchemaMerger(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema);
+
+ /**
+ * Returns the merged schema.
+ */
+ XsdSchema::Ptr mergedSchema() const;
+
+ private:
+ void merge(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema);
+
+ XsdSchema::Ptr m_mergedSchema;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp
new file mode 100644
index 0000000..c57d9fd
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp
@@ -0,0 +1,6119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaparser_p.h"
+
+#include "private/qxmlutils_p.h"
+#include "qacceltreeresourceloader_p.h"
+#include "qautoptr_p.h"
+#include "qboolean_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qqnamevalue_p.h"
+#include "qxmlquery_p.h"
+#include "qxpathhelper_p.h"
+#include "qxsdattributereference_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschematoken_p.h"
+
+#include <QtCore/QFile>
+#include <QtXmlPatterns/QXmlQuery>
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @page schema_overview Overview
+ * @section structure_and_components Structure and Components
+ *
+ * The schema validator code consists of 4 major components
+ *
+ * <dl>
+ * <dt>The schema parser (QPatternist::XsdSchemaParser)</dt>
+ * <dd>This component parses a XML document that is supplied via a QIODevice. It creates
+ * a so called (incomplete) 'compiled schema', which is a representation of the XML Schema
+ * structure as C++ objects.
+ * As the parser is a streaming parser, it can't resolve references to types or elements/attributes
+ * in place, therefor it creates resolver tasks which are passed to the schema resolver component
+ * for resolving at a later point in time.
+ * The parser does furthermore the basic XML structure constraint checking, e.g. if all required
+ * attributes are available or the order of the elements is correct.</dd>
+ *
+ * <dt>The schema resolver (QPatternist::XsdSchemaResolver)</dt>
+ * <dd>This component is activated after the schema parser component has been finished the parsing
+ * of all schemas. The resolver has been supplied with resolve tasks by the schema parser that
+ * it will resolve in this step now. Between working on the single resolver tasks, the resolver
+ * calls check methods from the schema checker component to make sure that some assertions are
+ * valid (e.g. no circular inheritance of types), so that the resolver can work without hassle.
+ * During resoving references to attribute or element groups it also checks for circular references
+ * of these groups.
+ * At the end of that phase we have a compiled schema that is fully resolved (not necessarily valid though).</dd>
+ *
+ * <dt>The schema checker (QPatternist::XsdSchemaChecker)</dt>
+ * <dd>This component does all the schema constraint checking as given by the Schema specification.
+ * At the end of that phase we have fully resolved and valid compiled schema that can be used for validation
+ * of instance documents.</dd>
+ *
+ * <dt>The validator (QPatternist::XsdValidatingInstanceReader)</dt>
+ * <dd>This component is responsible for validating a XML instance document, provided via a QIODevice, against
+ * a valid compiled schema.</dd>
+ * </dl>
+ *
+ * @ingroup Patternist_schema
+ */
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+
+/**
+ * @short A helper class for automatically handling namespace scopes of elements.
+ *
+ * This class should be instantiated at the beginning of each parse XYZ method.
+ */
+class ElementNamespaceHandler
+{
+ public:
+ /**
+ * Creates a new element namespace handler object.
+ *
+ * It checks whether the @p parser is on the right @p tag and it creates a new namespace
+ * context that contains the inherited and local namespace declarations.
+ */
+ ElementNamespaceHandler(const XsdSchemaToken::NodeName &tag, XsdSchemaParser *parser)
+ : m_parser(parser)
+ {
+ Q_ASSERT(m_parser->isStartElement() && (XsdSchemaToken::toToken(m_parser->name()) == tag) && (XsdSchemaToken::toToken(m_parser->namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI));
+ Q_UNUSED(tag)
+ m_parser->m_namespaceSupport.pushContext();
+ m_parser->m_namespaceSupport.setPrefixes(m_parser->namespaceDeclarations());
+ }
+
+ /**
+ * Destroys the element namespace handler object.
+ *
+ * It destroys the local namespace context.
+ */
+ ~ElementNamespaceHandler()
+ {
+ m_parser->m_namespaceSupport.popContext();
+ }
+
+ private:
+ XsdSchemaParser *m_parser;
+};
+
+/**
+ * A helper class that checks for the right occurrence of
+ * xml tags with the help of a DFA.
+ */
+class TagValidationHandler
+{
+ public:
+ TagValidationHandler(XsdTagScope::Type tag, XsdSchemaParser *parser, const NamePool::Ptr &namePool)
+ : m_parser(parser), m_machine(namePool)
+ {
+ Q_ASSERT(m_parser->m_stateMachines.contains(tag));
+
+ m_machine = m_parser->m_stateMachines.value(tag);
+ m_machine.reset();
+ }
+
+ void validate(XsdSchemaToken::NodeName token)
+ {
+ if (token == XsdSchemaToken::NoKeyword) {
+ const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
+
+ QStringList elementNames;
+ for (int i = 0; i < tokens.count(); ++i)
+ elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
+
+ m_parser->error(QtXmlPatterns::tr("Can not process unknown element %1, expected elements are: %2.")
+ .arg(formatElement(m_parser->name().toString()))
+ .arg(elementNames.join(QLatin1String(", "))));
+ return;
+ }
+
+ if (!m_machine.proceed(token)) {
+ const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
+
+ QStringList elementNames;
+ for (int i = 0; i < tokens.count(); ++i)
+ elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
+
+ m_parser->error(QtXmlPatterns::tr("Element %1 is not allowed in this scope, possible elements are: %2.")
+ .arg(formatElement(XsdSchemaToken::toString(token)))
+ .arg(elementNames.join(QLatin1String(", "))));
+ return;
+ }
+ }
+
+ void finalize() const
+ {
+ if (!m_machine.inEndState()) {
+ const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
+
+ QStringList elementNames;
+ for (int i = 0; i < tokens.count(); ++i)
+ elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
+
+ m_parser->error(QtXmlPatterns::tr("Child element is missing in that scope, possible child elements are: %1.")
+ .arg(elementNames.join(QLatin1String(", "))));
+ }
+ }
+
+ private:
+ XsdSchemaParser *m_parser;
+ XsdStateMachine<XsdSchemaToken::NodeName> m_machine;
+};
+
+}
+
+/**
+ * Returns a list of all particles with group references that appear at any level of
+ * the given unresolved @p group.
+ */
+static XsdParticle::List collectGroupRef(const XsdModelGroup::Ptr &group)
+{
+ XsdParticle::List refParticles;
+
+ XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ if (particles.at(i)->term()->isReference()) {
+ const XsdReference::Ptr reference(particles.at(i)->term());
+ if (reference->type() == XsdReference::ModelGroup)
+ refParticles.append(particles.at(i));
+ }
+ if (particles.at(i)->term()->isModelGroup()) {
+ refParticles << collectGroupRef(XsdModelGroup::Ptr(particles.at(i)->term()));
+ }
+ }
+
+ return refParticles;
+}
+
+/**
+ * Helper function that works around the limited facilities of
+ * QUrl/AnyURI::fromLexical to detect invalid URIs
+ */
+inline static bool isValidUri(const QString &string)
+{
+ // an empty URI points to the current document as defined in RFC 2396 (4.2)
+ if (string.isEmpty())
+ return true;
+
+ // explicit check as that is not checked by the code below
+ if (string.startsWith(QLatin1String("##")))
+ return false;
+
+ const AnyURI::Ptr uri = AnyURI::fromLexical(string);
+ return (!(uri->hasError()));
+}
+
+XsdSchemaParser::XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device)
+ : MaintainingReader<XsdSchemaToken, XsdTagScope::Type>(parserContext->elementDescriptions(), QSet<XsdSchemaToken::NodeName>(), context, device)
+ , m_context(context)
+ , m_parserContext(parserContext)
+ , m_namePool(m_parserContext->namePool())
+ , m_namespaceSupport(m_namePool)
+{
+ m_schema = m_parserContext->schema();
+ m_schemaResolver = m_parserContext->resolver();
+ m_idCache = XsdIdCache::Ptr(new XsdIdCache());
+
+ setupStateMachines();
+ setupBuiltinTypeNames();
+}
+
+void XsdSchemaParser::addIncludedSchemas(const NamespaceSet &schemas)
+{
+ m_includedSchemas += schemas;
+}
+
+void XsdSchemaParser::setIncludedSchemas(const NamespaceSet &schemas)
+{
+ m_includedSchemas = schemas;
+}
+
+void XsdSchemaParser::addImportedSchemas(const NamespaceSet &schemas)
+{
+ m_importedSchemas += schemas;
+}
+
+void XsdSchemaParser::setImportedSchemas(const NamespaceSet &schemas)
+{
+ m_importedSchemas = schemas;
+}
+
+void XsdSchemaParser::addRedefinedSchemas(const NamespaceSet &schemas)
+{
+ m_redefinedSchemas += schemas;
+}
+
+void XsdSchemaParser::setRedefinedSchemas(const NamespaceSet &schemas)
+{
+ m_redefinedSchemas = schemas;
+}
+
+void XsdSchemaParser::setTargetNamespace(const QString &targetNamespace)
+{
+ m_targetNamespace = targetNamespace;
+}
+
+void XsdSchemaParser::setTargetNamespaceExtended(const QString &targetNamespace)
+{
+ m_targetNamespace = targetNamespace;
+ m_namespaceSupport.setTargetNamespace(m_namePool->allocateNamespace(m_targetNamespace));
+}
+
+void XsdSchemaParser::setDocumentURI(const QUrl &uri)
+{
+ m_documentURI = uri;
+
+ // prevent to get included/imported/redefined twice
+ m_includedSchemas.insert(uri);
+ m_importedSchemas.insert(uri);
+ m_redefinedSchemas.insert(uri);
+}
+
+QUrl XsdSchemaParser::documentURI() const
+{
+ return m_documentURI;
+}
+
+bool XsdSchemaParser::isAnyAttributeAllowed() const
+{
+ return false;
+}
+
+bool XsdSchemaParser::parse(ParserType parserType)
+{
+ m_componentLocationHash.clear();
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ if (isSchemaTag(XsdSchemaToken::Schema, token, namespaceToken)) {
+ parseSchema(parserType);
+ } else {
+ error(QtXmlPatterns::tr("Document is not a XML schema."));
+ }
+ }
+ }
+
+ m_schemaResolver->addComponentLocationHash(m_componentLocationHash);
+ m_schemaResolver->setDefaultOpenContent(m_defaultOpenContent, m_defaultOpenContentAppliesToEmpty);
+
+ if (QXmlStreamReader::error() != QXmlStreamReader::NoError)
+ error(errorString());
+
+ return true;
+}
+
+void XsdSchemaParser::error(const QString &msg)
+{
+ MaintainingReader<XsdSchemaToken, XsdTagScope::Type>::error(msg, XsdSchemaContext::XSDError);
+}
+
+void XsdSchemaParser::attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type)
+{
+ if (type) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3} is not a value of type %4.")
+ .arg(formatAttribute(attributeName))
+ .arg(formatElement(elementName))
+ .arg(formatData(value))
+ .arg(formatType(m_namePool, type)));
+ } else {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3}.")
+ .arg(formatAttribute(attributeName))
+ .arg(formatElement(elementName))
+ .arg(formatData(value)));
+ }
+}
+
+void XsdSchemaParser::parseSchema(ParserType parserType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Schema, this);
+
+ validateElement(XsdTagScope::Schema);
+
+ // parse attributes
+
+ if (parserType == TopLevelParser) {
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ m_targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+ }
+ } else if (parserType == IncludeParser) {
+ // m_targetNamespace is set to the target namespace of the including schema at this point
+
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+
+ if (m_targetNamespace != targetNamespace) {
+ error(QtXmlPatterns::tr("Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema.")
+ .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ }
+ } else if (parserType == ImportParser) {
+ // m_targetNamespace is set to the target namespace from the namespace attribute of the <import> tag at this point
+
+ QString targetNamespace;
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+ }
+
+ if (m_targetNamespace != targetNamespace) {
+ error(QtXmlPatterns::tr("Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema.")
+ .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ } else if (parserType == RedefineParser) {
+ // m_targetNamespace is set to the target namespace of the redefining schema at this point
+
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+
+ if (m_targetNamespace != targetNamespace) {
+ error(QtXmlPatterns::tr("Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema.")
+ .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ }
+ }
+
+ if (hasAttribute(QString::fromLatin1("attributeFormDefault"))) {
+ const QString value = readAttribute(QString::fromLatin1("attributeFormDefault"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("attributeFormDefault", "schema", value);
+ return;
+ }
+
+ m_attributeFormDefault = value;
+ } else {
+ m_attributeFormDefault = QString::fromLatin1("unqualified");
+ }
+
+ if (hasAttribute(QString::fromLatin1("elementFormDefault"))) {
+ const QString value = readAttribute(QString::fromLatin1("elementFormDefault"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("elementFormDefault", "schema", value);
+ return;
+ }
+
+ m_elementFormDefault = value;
+ } else {
+ m_elementFormDefault = QString::fromLatin1("unqualified");
+ }
+
+ if (hasAttribute(QString::fromLatin1("blockDefault"))) {
+ const QString blockDefault = readAttribute(QString::fromLatin1("blockDefault"));
+ const QStringList blockDefaultList = blockDefault.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < blockDefaultList.count(); ++i) {
+ const QString value = blockDefaultList.at(i);
+ if (value != QString::fromLatin1("#all") &&
+ value != QString::fromLatin1("extension") &&
+ value != QString::fromLatin1("restriction") &&
+ value != QString::fromLatin1("substitution")) {
+ attributeContentError("blockDefault", "schema", value);
+ return;
+ }
+ }
+
+ m_blockDefault = blockDefault;
+ }
+
+ if (hasAttribute(QString::fromLatin1("finalDefault"))) {
+ const QString finalDefault = readAttribute(QString::fromLatin1("finalDefault"));
+ const QStringList finalDefaultList = finalDefault.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < finalDefaultList.count(); ++i) {
+ const QString value = finalDefaultList.at(i);
+ if (value != QString::fromLatin1("#all") &&
+ value != QString::fromLatin1("extension") &&
+ value != QString::fromLatin1("restriction") &&
+ value != QString::fromLatin1("list") &&
+ value != QString::fromLatin1("union")) {
+ attributeContentError("finalDefault", "schema", value);
+ return;
+ }
+ }
+
+ m_finalDefault = finalDefault;
+ }
+
+ if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) {
+ const QString xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace"));
+ if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##local")) {
+ if (!isValidUri(xpathDefaultNamespace)) {
+ attributeContentError("xpathDefaultNamespace", "schema", xpathDefaultNamespace);
+ return;
+ }
+ }
+ m_xpathDefaultNamespace = xpathDefaultNamespace;
+ } else {
+ m_xpathDefaultNamespace = QString::fromLatin1("##local");
+ }
+
+ if (hasAttribute(QString::fromLatin1("defaultAttributes"))) {
+ const QString attrGroupName = readQNameAttribute(QString::fromLatin1("defaultAttributes"), "schema");
+ convertName(attrGroupName, NamespaceSupport::ElementName, m_defaultAttributes); // translate qualified name into QXmlName
+ }
+
+ if (hasAttribute(QString::fromLatin1("version"))) {
+ const QString version = readAttribute(QString::fromLatin1("version"));
+ }
+
+ if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) {
+ const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML);
+
+ const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"));
+ if (!exp.exactMatch(value)) {
+ attributeContentError("xml:lang", "schema", value);
+ return;
+ }
+ }
+
+ validateIdAttribute("schema");
+
+ TagValidationHandler tagValidator(XsdTagScope::Schema, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Include, token, namespaceToken)) {
+ parseInclude();
+ } else if (isSchemaTag(XsdSchemaToken::Import, token, namespaceToken)) {
+ parseImport();
+ } else if (isSchemaTag(XsdSchemaToken::Redefine, token, namespaceToken)) {
+ parseRedefine();
+ } else if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::DefaultOpenContent, token, namespaceToken)) {
+ parseDefaultOpenContent();
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseGlobalSimpleType();
+ addType(type);
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ const XsdComplexType::Ptr type = parseGlobalComplexType();
+ addType(type);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdModelGroup::Ptr group = parseNamedGroup();
+ addElementGroup(group);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ XsdAttributeGroup::Ptr attributeGroup = parseNamedAttributeGroup();
+ addAttributeGroup(attributeGroup);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdElement::Ptr element = parseGlobalElement();
+ addElement(element);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttribute::Ptr attribute = parseGlobalAttribute();
+ addAttribute(attribute);
+ } else if (isSchemaTag(XsdSchemaToken::Notation, token, namespaceToken)) {
+ const XsdNotation::Ptr notation = parseNotation();
+ addNotation(notation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ m_schema->setTargetNamespace(m_targetNamespace);
+}
+
+void XsdSchemaParser::parseInclude()
+{
+ Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Include &&
+ XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
+
+ validateElement(XsdTagScope::Include);
+
+ // parse attributes
+ const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentURI.isValid());
+
+ url = m_documentURI.resolved(url);
+ }
+
+ if (m_includedSchemas.contains(url)) {
+ // we have included that file already, according to the schema spec we are
+ // allowed to silently skip it.
+ } else {
+ m_includedSchemas.insert(url);
+
+ const AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
+ m_context, AccelTreeResourceLoader::ContinueOnError));
+ if (reply) {
+ // parse the included schema by a different parser but with the same context
+ XsdSchemaParser parser(m_context, m_parserContext, reply.data());
+ parser.setDocumentURI(url);
+ parser.setTargetNamespaceExtended(m_targetNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::IncludeParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+ }
+ }
+
+ validateIdAttribute("include");
+
+ TagValidationHandler tagValidator(XsdTagScope::Include, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseImport()
+{
+ Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Import &&
+ XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
+
+ validateElement(XsdTagScope::Import);
+
+ // parse attributes
+ QString importNamespace;
+ if (hasAttribute(QString::fromLatin1("namespace"))) {
+ importNamespace = readAttribute(QString::fromLatin1("namespace"));
+ if (importNamespace == m_targetNamespace) {
+ error(QtXmlPatterns::tr("%1 element is not allowed to have the same %2 attribute value as the target namespace %3.")
+ .arg(formatElement("import"))
+ .arg(formatAttribute("namespace"))
+ .arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ } else {
+ if (m_targetNamespace.isEmpty()) {
+ error(QtXmlPatterns::tr("%1 element without %2 attribute is not allowed inside schema without target namespace.")
+ .arg(formatElement("import"))
+ .arg(formatAttribute("namespace")));
+ return;
+ }
+ }
+
+ if (hasAttribute(QString::fromLatin1("schemaLocation"))) {
+ const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentURI.isValid());
+
+ url = m_documentURI.resolved(url);
+ }
+
+ if (m_importedSchemas.contains(url)) {
+ // we have imported that file already, according to the schema spec we are
+ // allowed to silently skip it.
+ } else {
+ m_importedSchemas.insert(url);
+
+ // as it is possible that well known schemas (e.g. XSD for XML) are only referenced by
+ // namespace we should add it as well
+ m_importedSchemas.insert(importNamespace);
+
+ AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
+ m_context, AccelTreeResourceLoader::ContinueOnError));
+ if (reply) {
+ // parse the included schema by a different parser but with the same context
+ XsdSchemaParser parser(m_context, m_parserContext, reply.data());
+ parser.setDocumentURI(url);
+ parser.setTargetNamespace(importNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::ImportParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+ }
+ }
+ } else {
+ // check whether it is a known namespace we have a builtin schema for
+ if (!importNamespace.isEmpty()) {
+ if (!m_importedSchemas.contains(importNamespace)) {
+ m_importedSchemas.insert(importNamespace);
+
+ QFile file(QString::fromLatin1(":") + importNamespace);
+ if (file.open(QIODevice::ReadOnly)) {
+ XsdSchemaParser parser(m_context, m_parserContext, &file);
+ parser.setDocumentURI(importNamespace);
+ parser.setTargetNamespace(importNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::ImportParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+ }
+ }
+ } else {
+ // we don't import anything... that is valid according to the schema
+ }
+ }
+
+ validateIdAttribute("import");
+
+ TagValidationHandler tagValidator(XsdTagScope::Import, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseRedefine()
+{
+ Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Redefine &&
+ XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
+
+ validateElement(XsdTagScope::Redefine);
+
+ // parse attributes
+ validateIdAttribute("redefine");
+
+ const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
+
+ TagValidationHandler tagValidator(XsdTagScope::Redefine, this, m_namePool);
+
+ XsdSimpleType::List redefinedSimpleTypes;
+ XsdComplexType::List redefinedComplexTypes;
+ XsdModelGroup::List redefinedGroups;
+ XsdAttributeGroup::List redefinedAttributeGroups;
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseGlobalSimpleType();
+ redefinedSimpleTypes.append(type);
+
+ const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
+ if (baseTypeName != type->name(m_namePool)) {
+ error(QString::fromLatin1("redefined simple type %1 must have itself as base type").arg(formatType(m_namePool, type)));
+ return;
+ }
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ const XsdComplexType::Ptr type = parseGlobalComplexType();
+ redefinedComplexTypes.append(type);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
+
+ // 5
+ const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
+ if (baseTypeName != type->name(m_namePool)) {
+ error(QString::fromLatin1("redefined complex type %1 must have itself as base type").arg(formatType(m_namePool, type)));
+ return;
+ }
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdModelGroup::Ptr group = parseNamedGroup();
+ redefinedGroups.append(group);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeGroup::Ptr group = parseNamedAttributeGroup();
+ redefinedAttributeGroups.append(group);
+
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ bool locationMustResolve = false;
+ if (!redefinedSimpleTypes.isEmpty() || !redefinedComplexTypes.isEmpty() ||
+ !redefinedGroups.isEmpty() || !redefinedAttributeGroups.isEmpty()) {
+ locationMustResolve = true;
+ }
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentURI.isValid());
+
+ url = m_documentURI.resolved(url);
+ }
+
+ // we parse the schema given in the redefine tag into its own context
+ const XsdSchemaParserContext::Ptr redefinedContext(new XsdSchemaParserContext(m_namePool, m_context));
+
+ if (m_redefinedSchemas.contains(url)) {
+ // we have redefined that file already, according to the schema spec we are
+ // allowed to silently skip it.
+ } else {
+ m_redefinedSchemas.insert(url);
+ QNetworkReply *reply = AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
+ m_context,
+ (locationMustResolve ? AccelTreeResourceLoader::FailOnError : AccelTreeResourceLoader::ContinueOnError));
+ if (reply) {
+ // parse the included schema by a different parser but with the same context
+ XsdSchemaParser parser(m_context, redefinedContext, reply);
+ parser.setDocumentURI(url);
+ parser.setTargetNamespaceExtended(m_targetNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::RedefineParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+
+ delete reply;
+ }
+ }
+
+ XsdSimpleType::List contextSimpleTypes = redefinedContext->schema()->simpleTypes();
+ XsdComplexType::List contextComplexTypes = redefinedContext->schema()->complexTypes();
+ XsdModelGroup::List contextGroups = redefinedContext->schema()->elementGroups();
+ XsdAttributeGroup::List contextAttributeGroups = redefinedContext->schema()->attributeGroups();
+
+ // now we do the actual redefinition:
+
+ // iterate over all redefined simple types
+ for (int i = 0; i < redefinedSimpleTypes.count(); ++i) {
+ XsdSimpleType::Ptr redefinedType = redefinedSimpleTypes.at(i);
+
+ //TODONEXT: validation
+
+ // search the definition they override in the context types
+ bool found = false;
+ for (int j = 0; j < contextSimpleTypes.count(); ++j) {
+ XsdSimpleType::Ptr contextType = contextSimpleTypes.at(j);
+
+ if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type
+ found = true;
+
+ // 1) set name of context type to empty name
+ contextType->setName(m_parserContext->createAnonymousName(QString()));
+
+ // 2) set the context type as base type for the redefined type
+ redefinedType->setWxsSuperType(contextType);
+
+ // 3) remove the base type resolving job from the resolver as
+ // we have set the base type here explicitly
+ m_parserContext->resolver()->removeSimpleRestrictionBase(redefinedType);
+
+ // 4) add the redefined type to the schema
+ addType(redefinedType);
+
+ // 5) add the context type as anonymous type, so the resolver
+ // can resolve it further.
+ addAnonymousType(contextType);
+
+ // 6) remove the context type from the list
+ contextSimpleTypes.removeAt(j);
+
+ break;
+ }
+ }
+
+ if (!found) {
+ error(QString::fromLatin1("no matching type found to redefine simple type %1").arg(formatType(m_namePool, redefinedType)));
+ return;
+ }
+ }
+
+ // add all remaining context simple types to the schema
+ for (int i = 0; i < contextSimpleTypes.count(); ++i) {
+ addType(contextSimpleTypes.at(i));
+ }
+
+ // iterate over all redefined complex types
+ for (int i = 0; i < redefinedComplexTypes.count(); ++i) {
+ XsdComplexType::Ptr redefinedType = redefinedComplexTypes.at(i);
+
+ //TODONEXT: validation
+
+ // search the definition they override in the context types
+ bool found = false;
+ for (int j = 0; j < contextComplexTypes.count(); ++j) {
+ XsdComplexType::Ptr contextType = contextComplexTypes.at(j);
+
+ if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type
+ found = true;
+
+ // 1) set name of context type to empty name
+ contextType->setName(m_parserContext->createAnonymousName(QString()));
+
+ // 2) set the context type as base type for the redefined type
+ redefinedType->setWxsSuperType(contextType);
+
+ // 3) remove the base type resolving job from the resolver as
+ // we have set the base type here explicitly
+ m_parserContext->resolver()->removeComplexBaseType(redefinedType);
+
+ // 4) add the redefined type to the schema
+ addType(redefinedType);
+
+ // 5) add the context type as anonymous type, so the resolver
+ // can resolve its attribute uses etc.
+ addAnonymousType(contextType);
+
+ // 6) remove the context type from the list
+ contextComplexTypes.removeAt(j);
+
+ break;
+ }
+ }
+
+ if (!found) {
+ error(QString::fromLatin1("no matching type found to redefine complex type %1").arg(formatType(m_namePool, redefinedType)));
+ return;
+ }
+ }
+
+ // iterate over all redefined element groups
+ for (int i = 0; i < redefinedGroups.count(); ++i) {
+ const XsdModelGroup::Ptr group(redefinedGroups.at(i));
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
+
+ // 6
+ const XsdParticle::List particles = collectGroupRef(group);
+ XsdParticle::Ptr referencedParticle;
+ int sameNameCounter = 0;
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdReference::Ptr ref(particles.at(i)->term());
+ if (ref->referenceName() == group->name(m_namePool)) {
+ referencedParticle = particles.at(i);
+
+ if (referencedParticle->minimumOccurs() != 1 || referencedParticle->maximumOccurs() != 1 || referencedParticle->maximumOccursUnbounded()) { // 6.1.2
+ error(QString::fromLatin1("redefined group %1 can not contain reference to itself with minOccurs or maxOccurs != 1").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+ sameNameCounter++;
+ }
+ }
+
+ // 6.1.1
+ if (sameNameCounter > 1) {
+ error(QString::fromLatin1("redefined group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ // search the group definition in the included schema (S2)
+ XsdModelGroup::Ptr contextGroup;
+ for (int j = 0; j < contextGroups.count(); ++j) {
+ if (group->name(m_namePool) == contextGroups.at(j)->name(m_namePool)) {
+ contextGroup = contextGroups.at(j);
+ break;
+ }
+ }
+
+ if (!contextGroup) { // 6.2.1
+ error(QString::fromLatin1("redefined group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ if (sameNameCounter == 1) {
+ // there was a self reference in the redefined group, so use the
+ // group from the included schema
+
+ // set a anonymous name to the group of the included schema
+ contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI())));
+
+ // replace the self-reference with the group from the included schema
+ referencedParticle->setTerm(contextGroup);
+
+ addElementGroup(group);
+
+ addElementGroup(contextGroup);
+ contextGroups.removeAll(contextGroup);
+ } else {
+ // there was no self reference in the redefined group
+
+ // just add the redefined group...
+ addElementGroup(group);
+
+ // we have to add them, otherwise it is not resolved and we can't validate it later
+ contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI())));
+ addElementGroup(contextGroup);
+
+ m_schemaResolver->addRedefinedGroups(group, contextGroup);
+
+ // ...and forget about the group from the included schema
+ contextGroups.removeAll(contextGroup);
+ }
+ }
+
+ // iterate over all redefined attribute groups
+ for (int i = 0; i < redefinedAttributeGroups.count(); ++i) {
+ const XsdAttributeGroup::Ptr group(redefinedAttributeGroups.at(i));
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
+
+ // 7
+
+ // 7.1
+ int sameNameCounter = 0;
+ for (int j = 0; j < group->attributeUses().count(); ++j) {
+ const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j));
+ if (attributeUse->isReference()) {
+ const XsdAttributeReference::Ptr reference(attributeUse);
+ if (reference->type() == XsdAttributeReference::AttributeGroup) {
+ if (group->name(m_namePool) == reference->referenceName())
+ sameNameCounter++;
+ }
+ }
+ }
+ if (sameNameCounter > 1) {
+ error(QString::fromLatin1("redefined attribute group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ // search the attribute group definition in the included schema (S2)
+ XsdAttributeGroup::Ptr baseGroup;
+ for (int j = 0; j < contextAttributeGroups.count(); ++j) {
+ const XsdAttributeGroup::Ptr contextGroup(contextAttributeGroups.at(j));
+ if (group->name(m_namePool) == contextGroup->name(m_namePool)) {
+ baseGroup = contextGroup;
+ break;
+ }
+ }
+
+ if (!baseGroup) { // 7.2.1
+ error(QString::fromLatin1("redefined attribute group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ if (sameNameCounter == 1) {
+
+ // first set an anonymous name to the attribute group from the included
+ // schema
+ baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI())));
+
+ // iterate over the attribute uses of the redefined attribute group
+ // and replace the self-reference with the attribute group from the
+ // included schema
+ for (int j = 0; j < group->attributeUses().count(); ++j) {
+ const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j));
+ if (attributeUse->isReference()) {
+ const XsdAttributeReference::Ptr reference(attributeUse);
+ if (reference->type() == XsdAttributeReference::AttributeGroup) {
+ if (group->name(m_namePool) == reference->referenceName()) {
+ reference->setReferenceName(baseGroup->name(m_namePool));
+ break;
+ }
+ }
+ }
+ }
+
+ // add both groups to the target schema
+ addAttributeGroup(baseGroup);
+ addAttributeGroup(group);
+
+ contextAttributeGroups.removeAll(baseGroup);
+ }
+
+ if (sameNameCounter == 0) { // 7.2
+
+ // we have to add them, otherwise it is not resolved and we can't validate it later
+ baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI())));
+ addAttributeGroup(baseGroup);
+
+ m_schemaResolver->addRedefinedAttributeGroups(group, baseGroup);
+
+ // just add the redefined attribute group to the target schema...
+ addAttributeGroup(group);
+
+ // ... and forget about the one from the included schema
+ contextAttributeGroups.removeAll(baseGroup);
+ }
+ }
+
+ // add all remaining context complex types to the schema
+ for (int i = 0; i < contextComplexTypes.count(); ++i) {
+ addType(contextComplexTypes.at(i));
+ }
+
+ // add all remaining context element groups to the schema
+ for (int i = 0; i < contextGroups.count(); ++i) {
+ addElementGroup(contextGroups.at(i));
+ }
+
+ // add all remaining context attribute groups to the schema
+ for (int i = 0; i < contextAttributeGroups.count(); ++i) {
+ addAttributeGroup(contextAttributeGroups.at(i));
+ }
+
+ // copy all elements, attributes and notations
+ const XsdElement::List contextElements = redefinedContext->schema()->elements();
+ for (int i = 0; i < contextElements.count(); ++i) {
+ addElement(contextElements.at(i));
+ }
+
+ const XsdAttribute::List contextAttributes = redefinedContext->schema()->attributes();
+ for (int i = 0; i < contextAttributes.count(); ++i) {
+ addAttribute(contextAttributes.at(i));
+ }
+
+ const XsdNotation::List contextNotations = redefinedContext->schema()->notations();
+ for (int i = 0; i < contextNotations.count(); ++i) {
+ addNotation(contextNotations.at(i));
+ }
+
+ // push all data to resolve from the context resolver to our resolver
+ redefinedContext->resolver()->copyDataTo(m_parserContext->resolver());
+
+ tagValidator.finalize();
+}
+
+XsdAnnotation::Ptr XsdSchemaParser::parseAnnotation()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Annotation, this);
+
+ validateElement(XsdTagScope::Annotation);
+
+ // parse attributes
+ validateIdAttribute("annotation");
+
+ TagValidationHandler tagValidator(XsdTagScope::Annotation, this, m_namePool);
+
+ const XsdAnnotation::Ptr annotation(new XsdAnnotation());
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Appinfo, token, namespaceToken)) {
+ const XsdApplicationInformation::Ptr info = parseAppInfo();
+ annotation->addApplicationInformation(info);
+ } else if (isSchemaTag(XsdSchemaToken::Documentation, token, namespaceToken)) {
+ const XsdDocumentation::Ptr documentation = parseDocumentation();
+ annotation->addDocumentation(documentation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return annotation;
+}
+
+XsdApplicationInformation::Ptr XsdSchemaParser::parseAppInfo()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Appinfo, this);
+
+ validateElement(XsdTagScope::AppInfo);
+
+ const XsdApplicationInformation::Ptr info(new XsdApplicationInformation());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("source"))) {
+ const QString value = readAttribute(QString::fromLatin1("source"));
+
+ if (!isValidUri(value)) {
+ attributeContentError("source", "appinfo", value, BuiltinTypes::xsAnyURI);
+ return info;
+ }
+
+ if (!value.isEmpty()) {
+ const AnyURI::Ptr source = AnyURI::fromLexical(value);
+ info->setSource(source);
+ }
+ }
+
+ while (!atEnd()) { //EVAL: can be anything... what to do?
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknownDocumentation();
+ }
+
+ return info;
+}
+
+XsdDocumentation::Ptr XsdSchemaParser::parseDocumentation()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Documentation, this);
+
+ validateElement(XsdTagScope::Documentation);
+
+ const XsdDocumentation::Ptr documentation(new XsdDocumentation());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("source"))) {
+ const QString value = readAttribute(QString::fromLatin1("source"));
+
+ if (!isValidUri(value)) {
+ attributeContentError("source", "documentation", value, BuiltinTypes::xsAnyURI);
+ return documentation;
+ }
+
+ if (!value.isEmpty()) {
+ const AnyURI::Ptr source = AnyURI::fromLexical(value);
+ documentation->setSource(source);
+ }
+ }
+
+ if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) {
+ const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML);
+
+ const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"));
+ if (!exp.exactMatch(value)) {
+ attributeContentError("xml:lang", "documentation", value);
+ return documentation;
+ }
+ }
+
+ while (!atEnd()) { //EVAL: can by any... what to do?
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknownDocumentation();
+ }
+
+ return documentation;
+}
+
+void XsdSchemaParser::parseDefaultOpenContent()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::DefaultOpenContent, this);
+
+ validateElement(XsdTagScope::DefaultOpenContent);
+
+ m_defaultOpenContent = XsdComplexType::OpenContent::Ptr(new XsdComplexType::OpenContent());
+
+ if (hasAttribute(QString::fromLatin1("appliesToEmpty"))) {
+ const QString value = readAttribute(QString::fromLatin1("appliesToEmpty"));
+ const Boolean::Ptr appliesToEmpty = Boolean::fromLexical(value);
+ if (appliesToEmpty->hasError()) {
+ attributeContentError("appliesToEmpty", "defaultOpenContent", value, BuiltinTypes::xsBoolean);
+ return;
+ }
+
+ m_defaultOpenContentAppliesToEmpty = appliesToEmpty->as<Boolean>()->value();
+ } else {
+ m_defaultOpenContentAppliesToEmpty = false;
+ }
+
+ if (hasAttribute(QString::fromLatin1("mode"))) {
+ const QString mode = readAttribute(QString::fromLatin1("mode"));
+
+ if (mode == QString::fromLatin1("interleave")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
+ } else if (mode == QString::fromLatin1("suffix")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix);
+ } else {
+ attributeContentError("mode", "defaultOpenContent", mode);
+ return;
+ }
+ } else {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
+ }
+
+ validateIdAttribute("defaultOpenContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::DefaultOpenContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_defaultOpenContent->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle;
+ const XsdWildcard::Ptr wildcard = parseAny(particle);
+ m_defaultOpenContent->setWildcard(wildcard);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+XsdSimpleType::Ptr XsdSchemaParser::parseGlobalSimpleType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
+
+ validateElement(XsdTagScope::GlobalSimpleType);
+
+ const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
+ simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
+
+ // parse attributes
+ const SchemaType::DerivationConstraints allowedConstraints(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint | SchemaType::ListConstraint | SchemaType::UnionConstraint);
+ simpleType->setDerivationConstraints(readDerivationConstraintAttribute(allowedConstraints, "simpleType"));
+
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("simpleType"));
+ simpleType->setName(objectName);
+
+ validateIdAttribute("simpleType");
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalSimpleType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ simpleType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseSimpleRestriction(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) {
+ parseList(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) {
+ parseUnion(simpleType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return simpleType;
+}
+
+XsdSimpleType::Ptr XsdSchemaParser::parseLocalSimpleType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
+
+ validateElement(XsdTagScope::LocalSimpleType);
+
+ const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
+ simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
+ simpleType->setName(m_parserContext->createAnonymousName(m_targetNamespace));
+
+ validateIdAttribute("simpleType");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalSimpleType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ simpleType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseSimpleRestriction(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) {
+ parseList(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) {
+ parseUnion(simpleType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return simpleType;
+}
+
+void XsdSchemaParser::parseSimpleRestriction(const XsdSimpleType::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
+
+ validateElement(XsdTagScope::SimpleRestriction);
+
+ ptr->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+
+ // The base attribute and simpleType member are mutually exclusive,
+ // so we keep track of that
+ bool hasBaseAttribute = false;
+ bool hasBaseTypeSpecified = false;
+
+ QXmlName baseName;
+ if (hasAttribute(QString::fromLatin1("base"))) {
+ const QString base = readQNameAttribute(QString::fromLatin1("base"), "restriction");
+ convertName(base, NamespaceSupport::ElementName, baseName); // translate qualified name into QXmlName
+ m_schemaResolver->addSimpleRestrictionBase(ptr, baseName, currentSourceLocation()); // add to resolver
+
+ hasBaseAttribute = true;
+ hasBaseTypeSpecified = true;
+ }
+ validateIdAttribute("restriction");
+
+ XsdFacet::Hash facets;
+ QList<XsdFacet::Ptr> patternFacets;
+ QList<XsdFacet::Ptr> enumerationFacets;
+ QList<XsdFacet::Ptr> assertionFacets;
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleRestriction, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ ptr->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasBaseAttribute) {
+ error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present.")
+ .arg(formatElement("simpleType"))
+ .arg(formatElement("restriction"))
+ .arg(formatAttribute("base")));
+ return;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(ptr);
+ ptr->setWxsSuperType(type);
+ ptr->setCategory(type->category());
+ hasBaseTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinExclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinInclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxExclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxInclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseTotalDigitsFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseFractionDigitsFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseLengthFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinLengthFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxLengthFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseEnumerationFacet();
+ enumerationFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseWhiteSpaceFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parsePatternFacet();
+ patternFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseAssertionFacet();
+ assertionFacets.append(facet);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasBaseTypeSpecified) {
+ error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
+ .arg(formatElement("restriction"))
+ .arg(formatAttribute("base"))
+ .arg(formatElement("simpleType")));
+ return;
+ }
+
+ // merge all pattern facets into one multi value facet
+ if (!patternFacets.isEmpty()) {
+ const XsdFacet::Ptr patternFacet(new XsdFacet());
+ patternFacet->setType(XsdFacet::Pattern);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < patternFacets.count(); ++i)
+ multiValue << patternFacets.at(i)->multiValue();
+
+ patternFacet->setMultiValue(multiValue);
+ addFacet(patternFacet, facets, ptr);
+ }
+
+ // merge all enumeration facets into one multi value facet
+ if (!enumerationFacets.isEmpty()) {
+ const XsdFacet::Ptr enumerationFacet(new XsdFacet());
+ enumerationFacet->setType(XsdFacet::Enumeration);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < enumerationFacets.count(); ++i)
+ multiValue << enumerationFacets.at(i)->multiValue();
+
+ enumerationFacet->setMultiValue(multiValue);
+ addFacet(enumerationFacet, facets, ptr);
+ }
+
+ // merge all assertion facets into one facet
+ if (!assertionFacets.isEmpty()) {
+ const XsdFacet::Ptr assertionFacet(new XsdFacet());
+ assertionFacet->setType(XsdFacet::Assertion);
+
+ XsdAssertion::List assertions;
+ for (int i = 0; i < assertionFacets.count(); ++i)
+ assertions << assertionFacets.at(i)->assertions();
+
+ assertionFacet->setAssertions(assertions);
+ addFacet(assertionFacet, facets, ptr);
+ }
+
+ ptr->setFacets(facets);
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseList(const XsdSimpleType::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::List, this);
+
+ validateElement(XsdTagScope::List);
+
+ ptr->setCategory(XsdSimpleType::SimpleTypeList);
+ ptr->setDerivationMethod(XsdSimpleType::DerivationList);
+ ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+
+ // The itemType attribute and simpleType member are mutually exclusive,
+ // so we keep track of that
+ bool hasItemTypeAttribute = false;
+ bool hasItemTypeSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("itemType"))) {
+ const QString itemType = readQNameAttribute(QString::fromLatin1("itemType"), "list");
+ QXmlName typeName;
+ convertName(itemType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addSimpleListType(ptr, typeName, currentSourceLocation()); // add to resolver
+
+ hasItemTypeAttribute = true;
+ hasItemTypeSpecified = true;
+ }
+
+ validateIdAttribute("list");
+
+ TagValidationHandler tagValidator(XsdTagScope::List, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ ptr->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasItemTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present.")
+ .arg(formatElement("simpleType"))
+ .arg(formatElement("list"))
+ .arg(formatAttribute("itemType")));
+ return;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(ptr);
+ ptr->setItemType(type);
+
+ hasItemTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasItemTypeSpecified) {
+ error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
+ .arg(formatElement("list"))
+ .arg(formatAttribute("itemType"))
+ .arg(formatElement("simpleType")));
+ return;
+ }
+
+ tagValidator.finalize();
+
+ // add the default white space facet that every simple type with list derivation has
+ const XsdFacet::Ptr defaultFacet(new XsdFacet());
+ defaultFacet->setType(XsdFacet::WhiteSpace);
+ defaultFacet->setFixed(true);
+ defaultFacet->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+ XsdFacet::Hash facets;
+ facets.insert(defaultFacet->type(), defaultFacet);
+ ptr->setFacets(facets);
+}
+
+void XsdSchemaParser::parseUnion(const XsdSimpleType::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Union, this);
+
+ validateElement(XsdTagScope::Union);
+
+ ptr->setCategory(XsdSimpleType::SimpleTypeUnion);
+ ptr->setDerivationMethod(XsdSimpleType::DerivationUnion);
+ ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+
+ // The memberTypes attribute is not allowed to be empty,
+ // so we keep track of that
+ bool hasMemberTypesAttribute = false;
+ bool hasMemberTypesSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("memberTypes"))) {
+ hasMemberTypesAttribute = true;
+
+ const QStringList memberTypes = readAttribute(QString::fromLatin1("memberTypes")).split(QLatin1Char(' '), QString::SkipEmptyParts);
+ QList<QXmlName> typeNames;
+
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ QXmlName typeName;
+ convertName(memberTypes.at(i), NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ typeNames.append(typeName);
+ }
+
+ if (!typeNames.isEmpty()) {
+ m_schemaResolver->addSimpleUnionTypes(ptr, typeNames, currentSourceLocation()); // add to resolver
+ hasMemberTypesSpecified = true;
+ }
+ }
+
+ validateIdAttribute("union");
+
+ AnySimpleType::List memberTypes;
+
+ TagValidationHandler tagValidator(XsdTagScope::Union, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ ptr->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(ptr);
+ memberTypes.append(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!memberTypes.isEmpty()) {
+ ptr->setMemberTypes(memberTypes);
+ hasMemberTypesSpecified = true;
+ }
+
+ if (!hasMemberTypesSpecified) {
+ error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
+ .arg(formatElement("union"))
+ .arg(formatAttribute("memberTypes"))
+ .arg(formatElement("simpleType")));
+ return;
+ }
+
+ tagValidator.finalize();
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMinExclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinExclusive, this);
+
+ validateElement(XsdTagScope::MinExclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MinimumExclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "minExclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as minExclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "minExclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("minExclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MinExclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMinInclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinInclusive, this);
+
+ validateElement(XsdTagScope::MinInclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MinimumInclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "minInclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as minInclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "minInclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("minInclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MinInclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMaxExclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxExclusive, this);
+
+ validateElement(XsdTagScope::MaxExclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MaximumExclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "maxExclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as maxExclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "maxExclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("maxExclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MaxExclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMaxInclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxInclusive, this);
+
+ validateElement(XsdTagScope::MaxInclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MaximumInclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "maxInclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as maxInclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "maxInclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("maxInclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MaxInclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseTotalDigitsFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::TotalDigits, this);
+
+ validateElement(XsdTagScope::TotalDigitsFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::TotalDigits);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "totalDigits", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypePositiveInteger>::Ptr integer = DerivedInteger<TypePositiveInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "totalDigits", value, BuiltinTypes::xsPositiveInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("totalDigits");
+
+ TagValidationHandler tagValidator(XsdTagScope::TotalDigitsFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseFractionDigitsFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::FractionDigits, this);
+
+ validateElement(XsdTagScope::FractionDigitsFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::FractionDigits);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "fractionDigits", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "fractionDigits", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("fractionDigits");
+
+ TagValidationHandler tagValidator(XsdTagScope::FractionDigitsFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseLengthFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Length, this);
+
+ validateElement(XsdTagScope::LengthFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Length);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "length", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "length", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("length");
+
+ TagValidationHandler tagValidator(XsdTagScope::LengthFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMinLengthFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinLength, this);
+
+ validateElement(XsdTagScope::MinLengthFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MinimumLength);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "minLength", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "minLength", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("minLength");
+
+ TagValidationHandler tagValidator(XsdTagScope::MinLengthFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMaxLengthFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxLength, this);
+
+ validateElement(XsdTagScope::MaxLengthFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MaximumLength);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "maxLength", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "maxLength", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("maxLength");
+
+ TagValidationHandler tagValidator(XsdTagScope::MaxLengthFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseEnumerationFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Enumeration, this);
+
+ validateElement(XsdTagScope::EnumerationFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Enumeration);
+
+ // parse attributes
+ facet->setFixed(false); // not defined in schema, but can't hurt
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+
+ // as enumeration can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "enumeration", value);
+ return facet;
+ } else {
+ AtomicValue::List multiValue;
+ multiValue << string;
+ facet->setMultiValue(multiValue);
+ }
+ m_schemaResolver->addEnumerationFacetValue(string, m_namespaceSupport);
+
+ validateIdAttribute("enumeration");
+
+ TagValidationHandler tagValidator(XsdTagScope::EnumerationFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseWhiteSpaceFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::WhiteSpace, this);
+
+ validateElement(XsdTagScope::WhiteSpaceFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::WhiteSpace);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "whiteSpace", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ if (value != XsdSchemaToken::toString(XsdSchemaToken::Collapse) &&
+ value != XsdSchemaToken::toString(XsdSchemaToken::Preserve) &&
+ value != XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
+ attributeContentError("value", "whiteSpace", value);
+ return facet;
+ } else {
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "whiteSpace", value);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+ }
+
+ validateIdAttribute("whiteSpace");
+
+ TagValidationHandler tagValidator(XsdTagScope::WhiteSpaceFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parsePatternFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Pattern, this);
+
+ validateElement(XsdTagScope::PatternFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Pattern);
+
+ // parse attributes
+
+ // as pattern can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "pattern", value);
+ return facet;
+ } else {
+ AtomicValue::List multiValue;
+ multiValue << string;
+ facet->setMultiValue(multiValue);
+ }
+
+ validateIdAttribute("pattern");
+
+ TagValidationHandler tagValidator(XsdTagScope::PatternFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseAssertionFacet()
+{
+ // this is just a wrapper function around the parseAssertion() method
+
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assertion, XsdTagScope::Assertion);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Assertion);
+ facet->setAssertions(XsdAssertion::List() << assertion);
+
+ return facet;
+}
+
+XsdComplexType::Ptr XsdSchemaParser::parseGlobalComplexType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
+
+ validateElement(XsdTagScope::GlobalComplexType);
+
+ bool hasTypeSpecified = false;
+ bool hasComplexContent = false;
+
+ const XsdComplexType::Ptr complexType(new XsdComplexType());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("abstract"))) {
+ const QString abstract = readAttribute(QString::fromLatin1("abstract"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(abstract);
+ if (value->hasError()) {
+ attributeContentError("abstract", "complexType", abstract, BuiltinTypes::xsBoolean);
+ return complexType;
+ }
+
+ complexType->setIsAbstract(value->as<Boolean>()->value());
+ } else {
+ complexType->setIsAbstract(false); // default value
+ }
+
+ complexType->setProhibitedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint, "complexType"));
+ complexType->setDerivationConstraints(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "complexType"));
+
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("complexType"));
+ complexType->setName(objectName);
+
+ bool effectiveMixed = false;
+ if (hasAttribute(QString::fromLatin1("mixed"))) {
+ const QString mixed = readAttribute(QString::fromLatin1("mixed"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(mixed);
+ if (value->hasError()) {
+ attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
+ return complexType;
+ }
+
+ effectiveMixed = value->as<Boolean>()->value();
+ }
+
+ validateIdAttribute("complexType");
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalComplexType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) {
+ if (effectiveMixed) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("complexType"))
+ .arg(formatElement("simpleContent"))
+ .arg(formatAttribute("mixed")));
+ return complexType;
+ }
+
+ parseSimpleContent(complexType);
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) {
+ bool mixed;
+ parseComplexContent(complexType, &mixed);
+ hasTypeSpecified = true;
+
+ effectiveMixed = (effectiveMixed || mixed);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ }
+
+ if (hasComplexContent == true) {
+ resolveComplexContentType(complexType, effectiveMixed);
+ }
+
+ return complexType;
+}
+
+XsdComplexType::Ptr XsdSchemaParser::parseLocalComplexType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
+
+ validateElement(XsdTagScope::LocalComplexType);
+
+ bool hasTypeSpecified = false;
+ bool hasComplexContent = true;
+
+ const XsdComplexType::Ptr complexType(new XsdComplexType());
+ complexType->setName(m_parserContext->createAnonymousName(m_targetNamespace));
+
+ // parse attributes
+ bool effectiveMixed = false;
+ if (hasAttribute(QString::fromLatin1("mixed"))) {
+ const QString mixed = readAttribute(QString::fromLatin1("mixed"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(mixed);
+ if (value->hasError()) {
+ attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
+ return complexType;
+ }
+
+ effectiveMixed = value->as<Boolean>()->value();
+ }
+
+ validateIdAttribute("complexType");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalComplexType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) {
+ parseSimpleContent(complexType);
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) {
+ bool mixed;
+ parseComplexContent(complexType, &mixed);
+ hasTypeSpecified = true;
+
+ effectiveMixed = (effectiveMixed || mixed);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ }
+
+ if (hasComplexContent == true) {
+ resolveComplexContentType(complexType, effectiveMixed);
+ }
+
+ return complexType;
+}
+
+void XsdSchemaParser::resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common
+
+ // 1
+ // the effectiveMixed contains the effective mixed value
+
+ // 2
+ bool hasEmptyContent = false;
+ if (!complexType->contentType()->particle()) {
+ hasEmptyContent = true; // 2.1.1
+ } else {
+ if (complexType->contentType()->particle()->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group = complexType->contentType()->particle()->term();
+ if (group->compositor() == XsdModelGroup::SequenceCompositor || group->compositor() == XsdModelGroup::AllCompositor) {
+ if (group->particles().isEmpty())
+ hasEmptyContent = true; // 2.1.2
+ } else if (group->compositor() == XsdModelGroup::ChoiceCompositor) {
+ if ((complexType->contentType()->particle()->minimumOccurs() == 0) && group->particles().isEmpty())
+ hasEmptyContent = true; // 2.1.3
+ }
+
+ if ((complexType->contentType()->particle()->maximumOccursUnbounded() == false) && (complexType->contentType()->particle()->maximumOccurs() == 0))
+ hasEmptyContent = true; // 2.1.4
+ }
+ }
+
+ const XsdParticle::Ptr explicitContent = (hasEmptyContent ? XsdParticle::Ptr() : complexType->contentType()->particle());
+
+ // do all the other work (3, 4, 5 and 6) in the resolver, as they need access to the base type object
+ m_schemaResolver->addComplexContentType(complexType, explicitContent, effectiveMixed);
+}
+
+void XsdSchemaParser::parseSimpleContent(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleContent, this);
+
+ validateElement(XsdTagScope::SimpleContent);
+
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::Simple);
+
+ // parse attributes
+ validateIdAttribute("simpleContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseSimpleContentRestriction(complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) {
+ parseSimpleContentExtension(complexType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
+
+ validateElement(XsdTagScope::SimpleContentRestriction);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+
+ validateIdAttribute("restriction");
+
+ XsdFacet::Hash facets;
+ QList<XsdFacet::Ptr> patternFacets;
+ QList<XsdFacet::Ptr> enumerationFacets;
+ QList<XsdFacet::Ptr> assertionFacets;
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleContentRestriction, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(complexType); //TODO: investigate what the schema spec really wants here?!?
+ complexType->contentType()->setSimpleType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinExclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinInclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxExclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxInclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseTotalDigitsFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseFractionDigitsFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseLengthFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinLengthFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxLengthFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseEnumerationFacet();
+ enumerationFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseWhiteSpaceFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parsePatternFacet();
+ patternFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseAssertionFacet();
+ assertionFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ // merge all pattern facets into one multi value facet
+ if (!patternFacets.isEmpty()) {
+ const XsdFacet::Ptr patternFacet(new XsdFacet());
+ patternFacet->setType(XsdFacet::Pattern);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < patternFacets.count(); ++i)
+ multiValue << patternFacets.at(i)->multiValue();
+
+ patternFacet->setMultiValue(multiValue);
+ addFacet(patternFacet, facets, complexType);
+ }
+
+ // merge all enumeration facets into one multi value facet
+ if (!enumerationFacets.isEmpty()) {
+ const XsdFacet::Ptr enumerationFacet(new XsdFacet());
+ enumerationFacet->setType(XsdFacet::Enumeration);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < enumerationFacets.count(); ++i)
+ multiValue << enumerationFacets.at(i)->multiValue();
+
+ enumerationFacet->setMultiValue(multiValue);
+ addFacet(enumerationFacet, facets, complexType);
+ }
+
+ // merge all assertion facets into one facet
+ if (!assertionFacets.isEmpty()) {
+ const XsdFacet::Ptr assertionFacet(new XsdFacet());
+ assertionFacet->setType(XsdFacet::Assertion);
+
+ XsdAssertion::List assertions;
+ for (int i = 0; i < assertionFacets.count(); ++i)
+ assertions << assertionFacets.at(i)->assertions();
+
+ assertionFacet->setAssertions(assertions);
+ addFacet(assertionFacet, facets, complexType);
+ }
+
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation(), facets); // add to resolver
+}
+
+void XsdSchemaParser::parseSimpleContentExtension(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
+
+ validateElement(XsdTagScope::SimpleContentExtension);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationExtension);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("extension");
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleContentExtension, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexContent, this);
+
+ validateElement(XsdTagScope::ComplexContent);
+
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("mixed"))) {
+ const QString mixedStr = readAttribute(QString::fromLatin1("mixed"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(mixedStr);
+ if (value->hasError()) {
+ attributeContentError("mixed", "complexType", mixedStr, BuiltinTypes::xsBoolean);
+ return;
+ }
+
+ *mixed = value->as<Boolean>()->value();
+ } else {
+ *mixed = false;
+ }
+
+ validateIdAttribute("complexContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::ComplexContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseComplexContentRestriction(complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) {
+ parseComplexContentExtension(complexType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseComplexContentRestriction(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
+
+ validateElement(XsdTagScope::ComplexContentRestriction);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("restriction");
+
+ TagValidationHandler tagValidator(XsdTagScope::ComplexContentRestriction, this, m_namePool);
+
+ bool hasContent = false;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasContent)
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseComplexContentExtension(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
+
+ validateElement(XsdTagScope::ComplexContentExtension);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationExtension);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("extension");
+
+ TagValidationHandler tagValidator(XsdTagScope::ComplexContentExtension, this, m_namePool);
+
+ bool hasContent = false;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasContent)
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
+
+ tagValidator.finalize();
+}
+
+
+XsdAssertion::Ptr XsdSchemaParser::parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag)
+{
+ const ElementNamespaceHandler namespaceHandler(nodeName, this);
+
+ validateElement(tag);
+
+ const XsdAssertion::Ptr assertion(new XsdAssertion());
+
+ // parse attributes
+
+ const XsdXPathExpression::Ptr expression = readXPathExpression("assertion");
+ assertion->setTest(expression);
+
+ const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "assertion");
+ expression->setExpression(test);
+
+ validateIdAttribute("assertion");
+
+ TagValidationHandler tagValidator(tag, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ assertion->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return assertion;
+}
+
+XsdComplexType::OpenContent::Ptr XsdSchemaParser::parseOpenContent()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::OpenContent, this);
+
+ validateElement(XsdTagScope::OpenContent);
+
+ const XsdComplexType::OpenContent::Ptr openContent(new XsdComplexType::OpenContent());
+
+ if (hasAttribute(QString::fromLatin1("mode"))) {
+ const QString mode = readAttribute(QString::fromLatin1("mode"));
+
+ if (mode == QString::fromLatin1("none")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::None);
+ } else if (mode == QString::fromLatin1("interleave")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
+ } else if (mode == QString::fromLatin1("suffix")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix);
+ } else {
+ attributeContentError("mode", "openContent", mode);
+ return openContent;
+ }
+ } else {
+ openContent->setMode(XsdComplexType::OpenContent::Interleave);
+ }
+
+ validateIdAttribute("openContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::OpenContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ openContent->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle;
+ const XsdWildcard::Ptr wildcard = parseAny(particle);
+ openContent->setWildcard(wildcard);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return openContent;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseNamedGroup()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
+
+ validateElement(XsdTagScope::NamedGroup);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ XsdModelGroup::Ptr group;
+
+ QXmlName objectName;
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("group"));
+ }
+
+ validateIdAttribute("group");
+
+ TagValidationHandler tagValidator(XsdTagScope::NamedGroup, this, m_namePool);
+
+ XsdAnnotation::Ptr annotation;
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ annotation = parseAnnotation();
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ group = parseAll(modelGroup);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ group = parseChoice(modelGroup);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ group = parseSequence(modelGroup);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ group->setName(objectName);
+
+ if (annotation)
+ group->addAnnotation(annotation);
+
+ return group;
+}
+
+XsdTerm::Ptr XsdSchemaParser::parseReferredGroup(const XsdParticle::Ptr &particle)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
+
+ validateElement(XsdTagScope::ReferredGroup);
+
+ const XsdReference::Ptr reference(new XsdReference());
+ reference->setType(XsdReference::ModelGroup);
+ reference->setSourceLocation(currentSourceLocation());
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "group")) {
+ return reference;
+ }
+
+ const QString value = readQNameAttribute(QString::fromLatin1("ref"), "group");
+ QXmlName referenceName;
+ convertName(value, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+ reference->setReferenceName(referenceName);
+
+ validateIdAttribute("group");
+
+ TagValidationHandler tagValidator(XsdTagScope::ReferredGroup, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ reference->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return reference;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseAll(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
+
+ validateElement(XsdTagScope::All);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::AllCompositor);
+
+ validateIdAttribute("all");
+
+ TagValidationHandler tagValidator(XsdTagScope::All, this, m_namePool);
+
+ XsdParticle::List particles;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must be %3 or %4.")
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("0"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
+
+ validateElement(XsdTagScope::LocalAll);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::AllCompositor);
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "all")) {
+ return modelGroup;
+ }
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3.")
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+ if (particle->minimumOccurs() != 0 && particle->minimumOccurs() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4.")
+ .arg(formatAttribute("minOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("0"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+
+ validateIdAttribute("all");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalAll, this, m_namePool);
+
+ XsdParticle::List particles;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4.")
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("0"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseChoice(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
+
+ validateElement(XsdTagScope::Choice);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor);
+
+ validateIdAttribute("choice");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::Choice, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
+
+ validateElement(XsdTagScope::LocalChoice);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor);
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "choice")) {
+ return modelGroup;
+ }
+
+ validateIdAttribute("choice");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalChoice, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseSequence(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
+
+ validateElement(XsdTagScope::Sequence);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ validateIdAttribute("sequence");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::Sequence, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
+
+ validateElement(XsdTagScope::LocalSequence);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "sequence")) {
+ return modelGroup;
+ }
+
+ validateIdAttribute("sequence");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalSequence, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
+
+ validateElement(XsdTagScope::GlobalAttribute);
+
+ const XsdAttribute::Ptr attribute(new XsdAttribute());
+ attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope()));
+ attribute->scope()->setVariety(XsdAttribute::Scope::Global);
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return attribute;
+ }
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
+ attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Default);
+ attribute->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
+ attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Fixed);
+ attribute->valueConstraint()->setValue(value);
+ }
+
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attribute"));
+ if ((objectName.namespaceURI() == StandardNamespaces::xsi) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) {
+
+ error(QtXmlPatterns::tr("Content of %1 attribute of %2 element must not be from namespace %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatURI(CommonNamespaces::XSI)));
+ return attribute;
+ }
+ if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatData("xmlns")));
+ return attribute;
+ }
+ attribute->setName(objectName);
+
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ hasTypeAttribute = true;
+
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver
+ hasTypeSpecified = true;
+ }
+
+ validateIdAttribute("attribute");
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalAttribute, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attribute->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("attribute"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ break;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(attribute);
+ attribute->setType(type);
+ hasTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasTypeSpecified) {
+ attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
+ return attribute;
+ }
+
+ tagValidator.finalize();
+
+ return attribute;
+}
+
+XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
+
+ validateElement(XsdTagScope::LocalAttribute);
+
+ bool hasRefAttribute = false;
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+
+ XsdAttributeUse::Ptr attributeUse;
+ if (hasAttribute(QString::fromLatin1("ref"))) {
+ const XsdAttributeReference::Ptr reference = XsdAttributeReference::Ptr(new XsdAttributeReference());
+ reference->setType(XsdAttributeReference::AttributeUse);
+ reference->setSourceLocation(currentSourceLocation());
+
+ attributeUse = reference;
+ hasRefAttribute = true;
+ } else {
+ attributeUse = XsdAttributeUse::Ptr(new XsdAttributeUse());
+ }
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return attributeUse;
+ }
+
+ if (hasRefAttribute) {
+ if (hasAttribute(QString::fromLatin1("form"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("form")));
+ return attributeUse;
+ }
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("name")));
+ return attributeUse;
+ }
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("type")));
+ return attributeUse;
+ }
+ }
+
+ // parse attributes
+
+ // default, fixed and use are handled by both, attribute use and attribute reference
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint()));
+ attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Default);
+ attributeUse->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint()));
+ attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Fixed);
+ attributeUse->valueConstraint()->setValue(value);
+ }
+
+ if (hasAttribute(QString::fromLatin1("use"))) {
+ const QString value = readAttribute(QString::fromLatin1("use"));
+ if (value != QString::fromLatin1("optional") &&
+ value != QString::fromLatin1("prohibited") &&
+ value != QString::fromLatin1("required")) {
+ attributeContentError("use", "attribute", value);
+ return attributeUse;
+ }
+
+ if (value == QString::fromLatin1("optional"))
+ attributeUse->setUseType(XsdAttributeUse::OptionalUse);
+ else if (value == QString::fromLatin1("prohibited"))
+ attributeUse->setUseType(XsdAttributeUse::ProhibitedUse);
+ else if (value == QString::fromLatin1("required"))
+ attributeUse->setUseType(XsdAttributeUse::RequiredUse);
+
+ if (attributeUse->valueConstraint() && attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Default && value != QString::fromLatin1("optional")) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have the value %3 because the %4 attribute is set.")
+ .arg(formatAttribute("use"))
+ .arg(formatElement("attribute"))
+ .arg(formatData("optional"))
+ .arg(formatElement("default")));
+ return attributeUse;
+ }
+ }
+
+ const XsdAttribute::Ptr attribute(new XsdAttribute());
+
+ attributeUse->setAttribute(attribute);
+ m_componentLocationHash.insert(attribute, currentSourceLocation());
+
+ attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope()));
+ attribute->scope()->setVariety(XsdAttribute::Scope::Local);
+ attribute->scope()->setParent(parent);
+
+ // now make a difference between attribute reference and attribute use
+ if (hasRefAttribute) {
+ const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attribute");
+ QXmlName referenceName;
+ convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+
+ const XsdAttributeReference::Ptr attributeReference = attributeUse;
+ attributeReference->setReferenceName(referenceName);
+ } else {
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ const QString attributeName = readNameAttribute("attribute");
+
+ QXmlName objectName;
+ if (hasAttribute(QString::fromLatin1("form"))) {
+ const QString value = readAttribute(QString::fromLatin1("form"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("form", "attribute", value);
+ return attributeUse;
+ }
+
+ if (value == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), attributeName);
+ }
+ } else {
+ if (m_attributeFormDefault == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), attributeName);
+ }
+ }
+
+ if ((objectName.namespaceURI() == StandardNamespaces::xsi) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) {
+
+ error(QtXmlPatterns::tr("Content of %1 attribute of %2 element must not be from namespace %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatURI(CommonNamespaces::XSI)));
+ return attributeUse;
+ }
+ if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatData("xmlns")));
+ return attributeUse;
+ }
+
+ attribute->setName(objectName);
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ hasTypeAttribute = true;
+
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver
+ hasTypeSpecified = true;
+ }
+
+ if (attributeUse->valueConstraint()) {
+ //TODO: check whether assigning the value constraint of the attribute use to the attribute is correct
+ if (!attribute->valueConstraint())
+ attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
+
+ attribute->valueConstraint()->setVariety((XsdAttribute::ValueConstraint::Variety)attributeUse->valueConstraint()->variety());
+ attribute->valueConstraint()->setValue(attributeUse->valueConstraint()->value());
+ attribute->valueConstraint()->setLexicalForm(attributeUse->valueConstraint()->lexicalForm());
+ }
+ }
+
+ validateIdAttribute("attribute");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalAttribute, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attribute->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("attribute"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ break;
+ }
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("attribute"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("ref")));
+ break;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(attribute);
+ attribute->setType(type);
+ hasTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasTypeSpecified) {
+ attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
+ }
+
+ tagValidator.finalize();
+
+ return attributeUse;
+}
+
+XsdAttributeGroup::Ptr XsdSchemaParser::parseNamedAttributeGroup()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
+
+ validateElement(XsdTagScope::NamedAttributeGroup);
+
+ const XsdAttributeGroup::Ptr attributeGroup(new XsdAttributeGroup());
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attributeGroup"));
+ attributeGroup->setName(objectName);
+
+ validateIdAttribute("attributeGroup");
+
+ TagValidationHandler tagValidator(XsdTagScope::NamedAttributeGroup, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attributeGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(attributeGroup);
+
+ if (attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
+ warning(QtXmlPatterns::tr("Specifying use='prohibited' inside an attribute group has no effect."));
+ } else {
+ attributeGroup->addAttributeUse(attributeUse);
+ }
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ attributeGroup->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ attributeGroup->setWildcard(wildcard);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return attributeGroup;
+}
+
+XsdAttributeUse::Ptr XsdSchemaParser::parseReferredAttributeGroup()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
+
+ validateElement(XsdTagScope::ReferredAttributeGroup);
+
+ const XsdAttributeReference::Ptr attributeReference(new XsdAttributeReference());
+ attributeReference->setType(XsdAttributeReference::AttributeGroup);
+ attributeReference->setSourceLocation(currentSourceLocation());
+
+ // parse attributes
+ const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attributeGroup");
+ QXmlName referenceName;
+ convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+ attributeReference->setReferenceName(referenceName);
+
+ validateIdAttribute("attributeGroup");
+
+ TagValidationHandler tagValidator(XsdTagScope::ReferredAttributeGroup, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attributeReference->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return attributeReference;
+}
+
+XsdElement::Ptr XsdSchemaParser::parseGlobalElement()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
+
+ validateElement(XsdTagScope::GlobalElement);
+
+ const XsdElement::Ptr element(new XsdElement());
+ element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope()));
+ element->scope()->setVariety(XsdElement::Scope::Global);
+
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+ bool hasSubstitutionGroup = false;
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("element"));
+ element->setName(objectName);
+
+ if (hasAttribute(QString::fromLatin1("abstract"))) {
+ const QString abstract = readAttribute(QString::fromLatin1("abstract"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(abstract);
+ if (value->hasError()) {
+ attributeContentError("abstract", "element", abstract, BuiltinTypes::xsBoolean);
+ return element;
+ }
+
+ element->setIsAbstract(value->as<Boolean>()->value());
+ } else {
+ element->setIsAbstract(false); // the default value
+ }
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return element;
+ }
+
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default);
+ element->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
+ element->valueConstraint()->setValue(value);
+ }
+
+ element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element"));
+ element->setSubstitutionGroupExclusions(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "element"));
+
+ if (hasAttribute(QString::fromLatin1("nillable"))) {
+ const QString nillable = readAttribute(QString::fromLatin1("nillable"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(nillable);
+ if (value->hasError()) {
+ attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
+ return element;
+ }
+
+ element->setIsNillable(value->as<Boolean>()->value());
+ } else {
+ element->setIsNillable(false); // the default value
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "element");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver
+
+ hasTypeAttribute = true;
+ hasTypeSpecified = true;
+ }
+
+ if (hasAttribute(QString::fromLatin1("substitutionGroup"))) {
+ QList<QXmlName> elementNames;
+
+ const QString value = readAttribute(QString::fromLatin1("substitutionGroup"));
+ const QStringList substitutionGroups = value.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ if (substitutionGroups.isEmpty()) {
+ attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName);
+ return element;
+ }
+
+ for (int i = 0; i < substitutionGroups.count(); ++i) {
+ const QString value = substitutionGroups.at(i).simplified();
+ if (!XPathHelper::isQName(value)) {
+ attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName);
+ return element;
+ }
+
+ QXmlName elementName;
+ convertName(value, NamespaceSupport::ElementName, elementName); // translate qualified name into QXmlName
+ elementNames.append(elementName);
+ }
+
+ m_schemaResolver->addSubstitutionGroupAffiliation(element, elementNames, currentSourceLocation()); // add to resolver
+
+ hasSubstitutionGroup = true;
+ }
+
+ validateIdAttribute("element");
+
+ XsdAlternative::List alternatives;
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalElement, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ element->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ return element;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("complexType"))
+ .arg(formatAttribute("type")));
+ return element;
+ }
+
+ const XsdComplexType::Ptr type = parseLocalComplexType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) {
+ const XsdAlternative::Ptr alternative = parseAlternative();
+ alternatives.append(alternative);
+ } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) {
+ const XsdIdentityConstraint::Ptr constraint = parseUnique();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) {
+ const XsdIdentityConstraint::Ptr constraint = parseKey();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) {
+ const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element);
+ element->addIdentityConstraint(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ if (hasSubstitutionGroup)
+ m_schemaResolver->addSubstitutionGroupType(element);
+ else
+ element->setType(BuiltinTypes::xsAnyType);
+ }
+
+ if (!alternatives.isEmpty()) {
+ element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable()));
+
+ for (int i = 0; i < alternatives.count(); ++i) {
+ if (alternatives.at(i)->test())
+ element->typeTable()->addAlternative(alternatives.at(i));
+
+ if (i == (alternatives.count() - 1)) { // the final one
+ if (!alternatives.at(i)->test()) {
+ element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
+ } else {
+ const XsdAlternative::Ptr alternative(new XsdAlternative());
+ if (element->type())
+ alternative->setType(element->type());
+ else
+ m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
+
+ element->typeTable()->setDefaultTypeDefinition(alternative);
+ }
+ }
+ }
+ }
+
+ return element;
+}
+
+XsdTerm::Ptr XsdSchemaParser::parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
+
+ validateElement(XsdTagScope::LocalElement);
+
+ bool hasRefAttribute = false;
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+
+ XsdTerm::Ptr term;
+ XsdElement::Ptr element;
+ if (hasAttribute(QString::fromLatin1("ref"))) {
+ term = XsdReference::Ptr(new XsdReference());
+ hasRefAttribute = true;
+ } else {
+ term = XsdElement::Ptr(new XsdElement());
+ element = term;
+ }
+
+ if (hasRefAttribute) {
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("name")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("block"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("block")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("nillable"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("nillable")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("default"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("default")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("fixed")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("form"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("form")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("type"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("type")));
+ return term;
+ }
+ }
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "element")) {
+ return element;
+ }
+
+ if (!hasAttribute(QString::fromLatin1("name")) && !hasAttribute(QString::fromLatin1("ref"))) {
+ error(QtXmlPatterns::tr("%1 element must have either %2 or %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("name"))
+ .arg(formatAttribute("ref")));
+ return element;
+ }
+
+ if (hasRefAttribute) {
+ const QString ref = readQNameAttribute(QString::fromLatin1("ref"), "element");
+ QXmlName referenceName;
+ convertName(ref, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+
+ const XsdReference::Ptr reference = term;
+ reference->setReferenceName(referenceName);
+ reference->setType(XsdReference::Element);
+ reference->setSourceLocation(currentSourceLocation());
+ } else {
+ element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope()));
+ element->scope()->setVariety(XsdElement::Scope::Local);
+ element->scope()->setParent(parent);
+
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ const QString elementName = readNameAttribute("element");
+
+ QXmlName objectName;
+ if (hasAttribute(QString::fromLatin1("form"))) {
+ const QString value = readAttribute(QString::fromLatin1("form"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("form", "element", value);
+ return element;
+ }
+
+ if (value == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), elementName);
+ }
+ } else {
+ if (m_elementFormDefault == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), elementName);
+ }
+ }
+
+ element->setName(objectName);
+ }
+
+ if (hasAttribute(QString::fromLatin1("nillable"))) {
+ const QString nillable = readAttribute(QString::fromLatin1("nillable"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(nillable);
+ if (value->hasError()) {
+ attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
+ return term;
+ }
+
+ element->setIsNillable(value->as<Boolean>()->value());
+ } else {
+ element->setIsNillable(false); // the default value
+ }
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return element;
+ }
+
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default);
+ element->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
+ element->valueConstraint()->setValue(value);
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "element");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver
+
+ hasTypeAttribute = true;
+ hasTypeSpecified = true;
+ }
+
+ element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element"));
+ }
+
+ validateIdAttribute("element");
+
+ XsdAlternative::List alternatives;
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalElement, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ term->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("ref")));
+ return term;
+ } else if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ return term;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("complexType"))
+ .arg(formatAttribute("ref")));
+ return term;
+ } else if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("complexType"))
+ .arg(formatAttribute("type")));
+ return term;
+ }
+
+ const XsdComplexType::Ptr type = parseLocalComplexType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("alternative"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdAlternative::Ptr alternative = parseAlternative();
+ alternatives.append(alternative);
+ } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("unique"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdIdentityConstraint::Ptr constraint = parseUnique();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("key"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdIdentityConstraint::Ptr constraint = parseKey();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("keyref"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element);
+ element->addIdentityConstraint(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified && !hasRefAttribute)
+ element->setType(BuiltinTypes::xsAnyType);
+
+ if (!hasRefAttribute && !alternatives.isEmpty()) {
+ element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable()));
+
+ for (int i = 0; i < alternatives.count(); ++i) {
+ if (alternatives.at(i)->test())
+ element->typeTable()->addAlternative(alternatives.at(i));
+
+ if (i == (alternatives.count() - 1)) { // the final one
+ if (!alternatives.at(i)->test()) {
+ element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
+ } else {
+ const XsdAlternative::Ptr alternative(new XsdAlternative());
+ if (element->type())
+ alternative->setType(element->type());
+ else
+ m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
+
+ element->typeTable()->setDefaultTypeDefinition(alternative);
+ }
+ }
+ }
+ }
+
+ return term;
+}
+
+XsdIdentityConstraint::Ptr XsdSchemaParser::parseUnique()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Unique, this);
+
+ validateElement(XsdTagScope::Unique);
+
+ const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
+ constraint->setCategory(XsdIdentityConstraint::Unique);
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("unique"));
+ constraint->setName(objectName);
+
+ validateIdAttribute("unique");
+
+ TagValidationHandler tagValidator(XsdTagScope::Unique, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ constraint->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
+ parseSelector(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
+ parseField(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ // add constraint to schema for further checking
+ addIdentityConstraint(constraint);
+
+ tagValidator.finalize();
+
+ return constraint;
+}
+
+XsdIdentityConstraint::Ptr XsdSchemaParser::parseKey()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Key, this);
+
+ validateElement(XsdTagScope::Key);
+
+ const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
+ constraint->setCategory(XsdIdentityConstraint::Key);
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("key"));
+ constraint->setName(objectName);
+
+ validateIdAttribute("key");
+
+ TagValidationHandler tagValidator(XsdTagScope::Key, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ constraint->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
+ parseSelector(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
+ parseField(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ // add constraint to schema for further checking
+ addIdentityConstraint(constraint);
+
+ tagValidator.finalize();
+
+ return constraint;
+}
+
+XsdIdentityConstraint::Ptr XsdSchemaParser::parseKeyRef(const XsdElement::Ptr &element)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Keyref, this);
+
+ validateElement(XsdTagScope::KeyRef);
+
+ const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
+ constraint->setCategory(XsdIdentityConstraint::KeyReference);
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("keyref"));
+ constraint->setName(objectName);
+
+ const QString refer = readQNameAttribute(QString::fromLatin1("refer"), "keyref");
+ QXmlName referenceName;
+ convertName(refer, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+ m_schemaResolver->addKeyReference(element, constraint, referenceName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("keyref");
+
+ TagValidationHandler tagValidator(XsdTagScope::KeyRef, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ constraint->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
+ parseSelector(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
+ parseField(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ // add constraint to schema for further checking
+ addIdentityConstraint(constraint);
+
+ tagValidator.finalize();
+
+ return constraint;
+}
+
+void XsdSchemaParser::parseSelector(const XsdIdentityConstraint::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Selector, this);
+
+ validateElement(XsdTagScope::Selector);
+
+ // parse attributes
+ const XsdXPathExpression::Ptr expression = readXPathExpression("selector");
+
+ const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathSelector, "selector");
+ expression->setExpression(xpath);
+
+ ptr->setSelector(expression);
+
+ validateIdAttribute("selector");
+
+ TagValidationHandler tagValidator(XsdTagScope::Selector, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ expression->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseField(const XsdIdentityConstraint::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Field, this);
+
+ validateElement(XsdTagScope::Field);
+
+ // parse attributes
+ const XsdXPathExpression::Ptr expression = readXPathExpression("field");
+
+ const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathField, "field");
+ expression->setExpression(xpath);
+
+ ptr->addField(expression);
+
+ validateIdAttribute("field");
+
+ TagValidationHandler tagValidator(XsdTagScope::Field, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ expression->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+XsdAlternative::Ptr XsdSchemaParser::parseAlternative()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Alternative, this);
+
+ validateElement(XsdTagScope::Alternative);
+
+ const XsdAlternative::Ptr alternative(new XsdAlternative());
+
+ bool hasTypeSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("test"))) {
+ const XsdXPathExpression::Ptr expression = readXPathExpression("alternative");
+
+ const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "alternative");
+ expression->setExpression(test);
+
+ alternative->setTest(expression);
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "alternative");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addAlternativeType(alternative, typeName, currentSourceLocation()); // add to resolver
+
+ hasTypeSpecified = true;
+ }
+
+ validateIdAttribute("alternative");
+
+ TagValidationHandler tagValidator(XsdTagScope::Alternative, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ alternative->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ alternative->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ const XsdComplexType::Ptr type = parseLocalComplexType();
+ alternative->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ error(QtXmlPatterns::tr("%1 element must have either %2 attribute or %3 or %4 as child element.")
+ .arg(formatElement("alternative"))
+ .arg(formatAttribute("type"))
+ .arg(formatElement("simpleType"))
+ .arg(formatElement("complexType")));
+ return alternative;
+ }
+
+ return alternative;
+}
+
+XsdNotation::Ptr XsdSchemaParser::parseNotation()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Notation, this);
+
+ validateElement(XsdTagScope::Notation);
+
+ const XsdNotation::Ptr notation(new XsdNotation());
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("notation"));
+ notation->setName(objectName);
+
+ bool hasOptionalAttribute = false;
+
+ if (hasAttribute(QString::fromLatin1("public"))) {
+ const QString value = readAttribute(QString::fromLatin1("public"));
+ if (!value.isEmpty()) {
+ const DerivedString<TypeToken>::Ptr publicId = DerivedString<TypeToken>::fromLexical(m_namePool, value);
+ if (publicId->hasError()) {
+ attributeContentError("public", "notation", value, BuiltinTypes::xsToken);
+ return notation;
+ }
+ notation->setPublicId(publicId);
+ }
+
+ hasOptionalAttribute = true;
+ }
+
+ if (hasAttribute(QString::fromLatin1("system"))) {
+ const QString value = readAttribute(QString::fromLatin1("system"));
+ if (!isValidUri(value)) {
+ attributeContentError("system", "notation", value, BuiltinTypes::xsAnyURI);
+ return notation;
+ }
+
+ if (!value.isEmpty()) {
+ const AnyURI::Ptr systemId = AnyURI::fromLexical(value);
+ notation->setSystemId(systemId);
+ }
+
+ hasOptionalAttribute = true;
+ }
+
+ if (!hasOptionalAttribute) {
+ error(QtXmlPatterns::tr("%1 element requires either %2 or %3 attribute.")
+ .arg(formatElement("notation"))
+ .arg(formatAttribute("public"))
+ .arg(formatAttribute("system")));
+ return notation;
+ }
+
+ validateIdAttribute("notation");
+
+ TagValidationHandler tagValidator(XsdTagScope::Notation, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isCharacters() || isEntityReference()) {
+ if (!text().toString().trimmed().isEmpty()) {
+ error(QtXmlPatterns::tr("Text or entity references not allowed inside %1 element").arg(formatElement("notation.")));
+ return notation;
+ }
+ }
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ notation->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return notation;
+}
+
+XsdWildcard::Ptr XsdSchemaParser::parseAny(const XsdParticle::Ptr &particle)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Any, this);
+
+ validateElement(XsdTagScope::Any);
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "any")) {
+ return wildcard;
+ }
+
+ if (hasAttribute(QString::fromLatin1("namespace"))) {
+ const QSet<QString> values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+ if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs.")
+ .arg(formatAttribute("namespace"))
+ .arg(formatElement("any"))
+ .arg(formatData("##any"))
+ .arg(formatData("##other")));
+ return wildcard;
+ }
+
+ if (values.contains(QString::fromLatin1("##any"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ } else if (values.contains(QString::fromLatin1("##other"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ if (!m_targetNamespace.isEmpty())
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
+ else
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ QStringList newValues = values.toList();
+
+ // replace the ##targetNamespace entry
+ for (int i = 0; i < newValues.count(); ++i) {
+ if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) {
+ if (!m_targetNamespace.isEmpty())
+ newValues[i] = m_targetNamespace;
+ else
+ newValues[i] = XsdWildcard::absentNamespace();
+ } else if (newValues.at(i) == QString::fromLatin1("##local")) {
+ newValues[i] = XsdWildcard::absentNamespace();
+ }
+ }
+
+ // check for invalid URIs
+ for (int i = 0; i < newValues.count(); ++i) {
+ const QString stringValue = newValues.at(i);
+ if (stringValue == XsdWildcard::absentNamespace())
+ continue;
+
+ if (!isValidUri(stringValue)) {
+ attributeContentError("namespace", "any", stringValue, BuiltinTypes::xsAnyURI);
+ return wildcard;
+ }
+ }
+
+ wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
+ }
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ }
+
+ if (hasAttribute(QString::fromLatin1("processContents"))) {
+ const QString value = readAttribute(QString::fromLatin1("processContents"));
+ if (value != QString::fromLatin1("lax") &&
+ value != QString::fromLatin1("skip") &&
+ value != QString::fromLatin1("strict")) {
+ attributeContentError("processContents", "any", value);
+ return wildcard;
+ }
+
+ if (value == QString::fromLatin1("lax")) {
+ wildcard->setProcessContents(XsdWildcard::Lax);
+ } else if (value == QString::fromLatin1("skip")) {
+ wildcard->setProcessContents(XsdWildcard::Skip);
+ } else if (value == QString::fromLatin1("strict")) {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+ } else {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+
+ validateIdAttribute("any");
+
+ TagValidationHandler tagValidator(XsdTagScope::Any, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ wildcard->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return wildcard;
+}
+
+XsdWildcard::Ptr XsdSchemaParser::parseAnyAttribute()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AnyAttribute, this);
+
+ validateElement(XsdTagScope::AnyAttribute);
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("namespace"))) {
+ const QSet<QString> values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+ if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs.")
+ .arg(formatAttribute("namespace"))
+ .arg(formatElement("anyAttribute"))
+ .arg(formatData("##any"))
+ .arg(formatData("##other")));
+ return wildcard;
+ }
+
+ if (values.contains(QString::fromLatin1("##any"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ } else if (values.contains(QString::fromLatin1("##other"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ if (!m_targetNamespace.isEmpty())
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
+ else
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ QStringList newValues = values.toList();
+
+ // replace the ##targetNamespace entry
+ for (int i = 0; i < newValues.count(); ++i) {
+ if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) {
+ if (!m_targetNamespace.isEmpty())
+ newValues[i] = m_targetNamespace;
+ else
+ newValues[i] = XsdWildcard::absentNamespace();
+ } else if (newValues.at(i) == QString::fromLatin1("##local")) {
+ newValues[i] = XsdWildcard::absentNamespace();
+ }
+ }
+
+ // check for invalid URIs
+ for (int i = 0; i < newValues.count(); ++i) {
+ const QString stringValue = newValues.at(i);
+ if (stringValue == XsdWildcard::absentNamespace())
+ continue;
+
+ if (!isValidUri(stringValue)) {
+ attributeContentError("namespace", "anyAttribute", stringValue, BuiltinTypes::xsAnyURI);
+ return wildcard;
+ }
+ }
+
+ wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
+ }
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ }
+
+ if (hasAttribute(QString::fromLatin1("processContents"))) {
+ const QString value = readAttribute(QString::fromLatin1("processContents"));
+ if (value != QString::fromLatin1("lax") &&
+ value != QString::fromLatin1("skip") &&
+ value != QString::fromLatin1("strict")) {
+ attributeContentError("processContents", "anyAttribute", value);
+ return wildcard;
+ }
+
+ if (value == QString::fromLatin1("lax")) {
+ wildcard->setProcessContents(XsdWildcard::Lax);
+ } else if (value == QString::fromLatin1("skip")) {
+ wildcard->setProcessContents(XsdWildcard::Skip);
+ } else if (value == QString::fromLatin1("strict")) {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+ } else {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+
+ validateIdAttribute("anyAttribute");
+
+ TagValidationHandler tagValidator(XsdTagScope::AnyAttribute, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ wildcard->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return wildcard;
+}
+
+
+void XsdSchemaParser::parseUnknownDocumentation()
+{
+ Q_ASSERT(isStartElement());
+ m_namespaceSupport.pushContext();
+ m_namespaceSupport.setPrefixes(namespaceDeclarations());
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknownDocumentation();
+ }
+
+ m_namespaceSupport.popContext();
+}
+
+void XsdSchemaParser::parseUnknown()
+{
+ Q_ASSERT(isStartElement());
+ m_namespaceSupport.pushContext();
+ m_namespaceSupport.setPrefixes(namespaceDeclarations());
+
+ error(QtXmlPatterns::tr("%1 element is not allowed in this context.").arg(formatElement(name().toString())));
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknown();
+ }
+
+ m_namespaceSupport.popContext();
+}
+
+bool XsdSchemaParser::parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char *elementName)
+{
+ if (hasAttribute(QString::fromLatin1("minOccurs"))) {
+ const QString value = readAttribute(QString::fromLatin1("minOccurs"));
+
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("minOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
+ return false;
+ } else {
+ particle->setMinimumOccurs(integer->as< DerivedInteger<TypeNonNegativeInteger> >()->storedValue());
+ }
+ } else {
+ particle->setMinimumOccurs(1);
+ }
+
+ if (hasAttribute(QString::fromLatin1("maxOccurs"))) {
+ const QString value = readAttribute(QString::fromLatin1("maxOccurs"));
+
+ if (value == QString::fromLatin1("unbounded")) {
+ particle->setMaximumOccursUnbounded(true);
+ } else {
+ particle->setMaximumOccursUnbounded(false);
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("maxOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
+ return false;
+ } else {
+ particle->setMaximumOccurs(integer->as< DerivedInteger<TypeNonNegativeInteger> >()->storedValue());
+ }
+ }
+ } else {
+ particle->setMaximumOccursUnbounded(false);
+ particle->setMaximumOccurs(1);
+ }
+
+ if (!particle->maximumOccursUnbounded()) {
+ if (particle->maximumOccurs() < particle->minimumOccurs()) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element has larger value than %3 attribute.")
+ .arg(formatAttribute("minOccurs"))
+ .arg(formatElement(elementName))
+ .arg(formatAttribute("maxOccurs")));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QSourceLocation XsdSchemaParser::currentSourceLocation() const
+{
+ QSourceLocation location;
+ location.setLine(lineNumber());
+ location.setColumn(columnNumber());
+ location.setUri(m_documentURI);
+
+ return location;
+}
+
+void XsdSchemaParser::convertName(const QString &qualifiedName, NamespaceSupport::NameType type, QXmlName &name)
+{
+ bool result = m_namespaceSupport.processName(qualifiedName, type, name);
+ if (!result) {
+ error(QtXmlPatterns::tr("Prefix of qualified name %1 is not defined.").arg(formatKeyword(qualifiedName)));
+ }
+}
+
+QString XsdSchemaParser::readNameAttribute(const char *elementName)
+{
+ const QString value = readAttribute(QString::fromLatin1("name")).simplified();
+ if (!QXmlUtils::isNCName(value)) {
+ attributeContentError("name", elementName, value, BuiltinTypes::xsNCName);
+ return QString();
+ } else {
+ return value;
+ }
+}
+
+QString XsdSchemaParser::readQNameAttribute(const QString &typeAttribute, const char *elementName)
+{
+ const QString value = readAttribute(typeAttribute).simplified();
+ if (!XPathHelper::isQName(value)) {
+ attributeContentError(typeAttribute.toLatin1(), elementName, value, BuiltinTypes::xsQName);
+ return QString();
+ } else {
+ return value;
+ }
+}
+
+QString XsdSchemaParser::readNamespaceAttribute(const QString &attributeName, const char *elementName)
+{
+ const QString value = readAttribute(attributeName);
+ if (value.isEmpty()) {
+ attributeContentError(attributeName.toLatin1(), elementName, value, BuiltinTypes::xsAnyURI);
+ return QString();
+ }
+
+ return value;
+}
+
+SchemaType::DerivationConstraints XsdSchemaParser::readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName)
+{
+ // first convert the flags into strings for easier comparison
+ QSet<QString> allowedContent;
+ if (allowedConstraints & SchemaType::RestrictionConstraint)
+ allowedContent.insert(QString::fromLatin1("restriction"));
+ if (allowedConstraints & SchemaType::ExtensionConstraint)
+ allowedContent.insert(QString::fromLatin1("extension"));
+ if (allowedConstraints & SchemaType::ListConstraint)
+ allowedContent.insert(QString::fromLatin1("list"));
+ if (allowedConstraints & SchemaType::UnionConstraint)
+ allowedContent.insert(QString::fromLatin1("union"));
+
+ // read content from the attribute if available, otherwise use the default definitions from the schema tag
+ QString content;
+ if (hasAttribute(QString::fromLatin1("final"))) {
+ content = readAttribute(QString::fromLatin1("final"));
+
+ // split string into list to validate the content of the attribute
+ const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < values.count(); i++) {
+ const QString value = values.at(i);
+ if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) {
+ attributeContentError("final", elementName, value);
+ return SchemaType::DerivationConstraints();
+ }
+
+ if ((value == QString::fromLatin1("#all")) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values.")
+ .arg(formatAttribute("final"))
+ .arg(formatElement(elementName))
+ .arg(formatData("#all")));
+ return SchemaType::DerivationConstraints();
+ }
+ }
+ } else {
+ // content of the default value has been validated in parseSchema already
+ content = m_finalDefault;
+ }
+
+ QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+
+ // if the '#all' tag is defined, we return all allowed values
+ if (contentSet.contains(QString::fromLatin1("#all"))) {
+ return allowedConstraints;
+ } else { // return the values from content set that intersects with the allowed values
+ contentSet.intersect(allowedContent);
+
+ SchemaType::DerivationConstraints constraints;
+
+ if (contentSet.contains(QString::fromLatin1("restriction")))
+ constraints |= SchemaType::RestrictionConstraint;
+ if (contentSet.contains(QString::fromLatin1("extension")))
+ constraints |= SchemaType::ExtensionConstraint;
+ if (contentSet.contains(QString::fromLatin1("list")))
+ constraints |= SchemaType::ListConstraint;
+ if (contentSet.contains(QString::fromLatin1("union")))
+ constraints |= SchemaType::UnionConstraint;
+
+ return constraints;
+ }
+}
+
+NamedSchemaComponent::BlockingConstraints XsdSchemaParser::readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName)
+{
+ // first convert the flags into strings for easier comparison
+ QSet<QString> allowedContent;
+ if (allowedConstraints & NamedSchemaComponent::RestrictionConstraint)
+ allowedContent.insert(QString::fromLatin1("restriction"));
+ if (allowedConstraints & NamedSchemaComponent::ExtensionConstraint)
+ allowedContent.insert(QString::fromLatin1("extension"));
+ if (allowedConstraints & NamedSchemaComponent::SubstitutionConstraint)
+ allowedContent.insert(QString::fromLatin1("substitution"));
+
+ // read content from the attribute if available, otherwise use the default definitions from the schema tag
+ QString content;
+ if (hasAttribute(QString::fromLatin1("block"))) {
+ content = readAttribute(QString::fromLatin1("block"));
+
+ // split string into list to validate the content of the attribute
+ const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < values.count(); i++) {
+ const QString value = values.at(i);
+ if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) {
+ attributeContentError("block", elementName, value);
+ return NamedSchemaComponent::BlockingConstraints();
+ }
+
+ if ((value == QString::fromLatin1("#all")) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values.")
+ .arg(formatAttribute("block"))
+ .arg(formatElement(elementName))
+ .arg(formatData("#all")));
+ return NamedSchemaComponent::BlockingConstraints();
+ }
+ }
+ } else {
+ // content of the default value has been validated in parseSchema already
+ content = m_blockDefault;
+ }
+
+ QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+
+ // if the '#all' tag is defined, we return all allowed values
+ if (contentSet.contains(QString::fromLatin1("#all"))) {
+ return allowedConstraints;
+ } else { // return the values from content set that intersects with the allowed values
+ contentSet.intersect(allowedContent);
+
+ NamedSchemaComponent::BlockingConstraints constraints;
+
+ if (contentSet.contains(QString::fromLatin1("restriction")))
+ constraints |= NamedSchemaComponent::RestrictionConstraint;
+ if (contentSet.contains(QString::fromLatin1("extension")))
+ constraints |= NamedSchemaComponent::ExtensionConstraint;
+ if (contentSet.contains(QString::fromLatin1("substitution")))
+ constraints |= NamedSchemaComponent::SubstitutionConstraint;
+
+ return constraints;
+ }
+}
+
+XsdXPathExpression::Ptr XsdSchemaParser::readXPathExpression(const char *elementName)
+{
+ const XsdXPathExpression::Ptr expression(new XsdXPathExpression());
+
+ const QList<QXmlName> namespaceBindings = m_namespaceSupport.namespaceBindings();
+ QXmlName emptyName;
+ for (int i = 0; i < namespaceBindings.count(); ++i) {
+ if (namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
+ emptyName = namespaceBindings.at(i);
+ }
+
+ expression->setNamespaceBindings(namespaceBindings);
+
+ QString xpathDefaultNamespace;
+ if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) {
+ xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace"));
+ if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##local")) {
+ if (!isValidUri(xpathDefaultNamespace)) {
+ attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI);
+ return expression;
+ }
+ }
+ } else {
+ xpathDefaultNamespace = m_xpathDefaultNamespace;
+ }
+
+ AnyURI::Ptr namespaceURI;
+ if (xpathDefaultNamespace == QString::fromLatin1("##defaultNamespace")) {
+ if (!emptyName.isNull())
+ namespaceURI = AnyURI::fromLexical(m_namePool->stringForNamespace(emptyName.namespaceURI()));
+ } else if (xpathDefaultNamespace == QString::fromLatin1("##targetNamespace")) {
+ if (!m_targetNamespace.isEmpty())
+ namespaceURI = AnyURI::fromLexical(m_targetNamespace);
+ } else if (xpathDefaultNamespace == QString::fromLatin1("##local")) {
+ // it is absent
+ } else {
+ namespaceURI = AnyURI::fromLexical(xpathDefaultNamespace);
+ }
+ if (namespaceURI) {
+ if (namespaceURI->hasError()) {
+ attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI);
+ return expression;
+ }
+
+ expression->setDefaultNamespace(namespaceURI);
+ }
+
+ //TODO: read the base uri if qmaintaining reader support it
+
+ return expression;
+}
+
+QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName)
+{
+ const QString value = readAttribute(attributeName);
+ if (value.isEmpty() || value.startsWith(QLatin1Char('/'))) {
+ attributeContentError(attributeName.toLatin1(), elementName, value);
+ return QString();
+ }
+
+ QXmlNamePool namePool(m_namePool.data());
+
+ QXmlQuery::QueryLanguage language = QXmlQuery::XPath20;
+ switch (type) {
+ case XPath20: language = QXmlQuery::XPath20; break;
+ case XPathSelector: language = QXmlQuery::XmlSchema11IdentityConstraintSelector; break;
+ case XPathField: language = QXmlQuery::XmlSchema11IdentityConstraintField; break;
+ };
+
+ QXmlQuery query(language, namePool);
+ QXmlQueryPrivate *queryPrivate = query.d;
+
+ const QList<QXmlName> namespaceBindings = m_namespaceSupport.namespaceBindings();
+ for (int i = 0; i < namespaceBindings.count(); ++i) {
+ if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
+ queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i));
+ }
+
+ query.setQuery(value, m_documentURI);
+ if (!query.isValid()) {
+ attributeContentError(attributeName.toLatin1(), elementName, value);
+ return QString();
+ }
+
+ return value;
+}
+
+void XsdSchemaParser::validateIdAttribute(const char *elementName)
+{
+ if (hasAttribute(QString::fromLatin1("id"))) {
+ const QString value = readAttribute(QString::fromLatin1("id"));
+ DerivedString<TypeID>::Ptr id = DerivedString<TypeID>::fromLexical(m_namePool, value);
+ if (id->hasError()) {
+ attributeContentError("id", elementName, value, BuiltinTypes::xsID);
+ } else {
+ if (m_idCache->hasId(value)) {
+ error(QtXmlPatterns::tr("Component with ID %1 has been defined previously.").arg(formatData(value)));
+ } else {
+ m_idCache->addId(value);
+ }
+ }
+ }
+}
+
+bool XsdSchemaParser::isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const
+{
+ return ((tag == token) && (namespaceToken == XsdSchemaToken::XML_NS_SCHEMA_URI));
+}
+
+void XsdSchemaParser::addElement(const XsdElement::Ptr &element)
+{
+ const QXmlName objectName = element->name(m_namePool);
+ if (m_schema->element(objectName)) {
+ error(QtXmlPatterns::tr("Element %1 already defined.").arg(formatElement(m_namePool->displayName(objectName))));
+ } else {
+ m_schema->addElement(element);
+ m_componentLocationHash.insert(element, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addAttribute(const XsdAttribute::Ptr &attribute)
+{
+ const QXmlName objectName = attribute->name(m_namePool);
+ if (m_schema->attribute(objectName)) {
+ error(QtXmlPatterns::tr("Attribute %1 already defined.").arg(formatAttribute(m_namePool->displayName(objectName))));
+ } else {
+ m_schema->addAttribute(attribute);
+ m_componentLocationHash.insert(attribute, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addType(const SchemaType::Ptr &type)
+{
+ // we don't import redefinitions of builtin types, that just causes problems
+ if (m_builtinTypeNames.contains(type->name(m_namePool)))
+ return;
+
+ const QXmlName objectName = type->name(m_namePool);
+ if (m_schema->type(objectName)) {
+ error(QtXmlPatterns::tr("Type %1 already defined.").arg(formatType(m_namePool, objectName)));
+ } else {
+ m_schema->addType(type);
+ if (type->isSimpleType())
+ m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation());
+ else
+ m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addAnonymousType(const SchemaType::Ptr &type)
+{
+ m_schema->addAnonymousType(type);
+ if (type->isSimpleType())
+ m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation());
+ else
+ m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation());
+}
+
+void XsdSchemaParser::addAttributeGroup(const XsdAttributeGroup::Ptr &group)
+{
+ const QXmlName objectName = group->name(m_namePool);
+ if (m_schema->attributeGroup(objectName)) {
+ error(QtXmlPatterns::tr("Attribute group %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addAttributeGroup(group);
+ m_componentLocationHash.insert(group, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addElementGroup(const XsdModelGroup::Ptr &group)
+{
+ const QXmlName objectName = group->name(m_namePool);
+ if (m_schema->elementGroup(objectName)) {
+ error(QtXmlPatterns::tr("Element group %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addElementGroup(group);
+ m_componentLocationHash.insert(group, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addNotation(const XsdNotation::Ptr &notation)
+{
+ const QXmlName objectName = notation->name(m_namePool);
+ if (m_schema->notation(objectName)) {
+ error(QtXmlPatterns::tr("Notation %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addNotation(notation);
+ m_componentLocationHash.insert(notation, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
+{
+ const QXmlName objectName = constraint->name(m_namePool);
+ if (m_schema->identityConstraint(objectName)) {
+ error(QtXmlPatterns::tr("Identity constraint %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addIdentityConstraint(constraint);
+ m_componentLocationHash.insert(constraint, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type)
+{
+ // @see http://www.w3.org/TR/xmlschema-2/#src-single-facet-value
+ if (facets.contains(facet->type())) {
+ error(QtXmlPatterns::tr("Duplicated facets in simple type %1.").arg(formatType(m_namePool, type)));
+ return;
+ }
+
+ facets.insert(facet->type(), facet);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaparser_p.h b/src/xmlpatterns/schema/qxsdschemaparser_p.h
new file mode 100644
index 0000000..80d44a5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparser_p.h
@@ -0,0 +1,739 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaParser_H
+#define Patternist_XsdSchemaParser_H
+
+#include "qnamespacesupport_p.h"
+#include "qxsdalternative_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdattributeterm_p.h"
+#include "qxsdcomplextype_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdidcache_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdsimpletype_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemaparsercontext_p.h"
+#include "qxsdstatemachine_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QUrl>
+#include <QtXml/QXmlStreamReader>
+#include <QtXmlPatterns/QXmlNamePool>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the parsing of XML schema file.
+ *
+ * This class parses a XML schema in XML presentation from an QIODevice
+ * and returns object representation as XsdSchema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaParser : public MaintainingReader<XsdSchemaToken, XsdTagScope::Type>
+ {
+ friend class ElementNamespaceHandler;
+ friend class TagValidationHandler;
+
+ public:
+ enum ParserType
+ {
+ TopLevelParser,
+ IncludeParser,
+ ImportParser,
+ RedefineParser
+ };
+
+ /**
+ * Creates a new schema parser object.
+ */
+ XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device);
+
+ /**
+ * Parses the XML schema file.
+ *
+ * @return @c true on success, @c false if the schema is somehow invalid.
+ */
+ bool parse(ParserType parserType = TopLevelParser);
+
+ /**
+ * Describes a set of namespace URIs
+ */
+ typedef QSet<QUrl> NamespaceSet;
+
+ /**
+ * Adds @p schemas to the list of already included schemas, so the parser
+ * can detect multiple includes of the same schema.
+ */
+ void addIncludedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets which @p schemas have been included already, so the parser
+ * can detect multiple includes of the same schema.
+ */
+ void setIncludedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Adds @p schemas to the list of already imported schemas, so the parser
+ * can detect multiple imports of the same schema.
+ */
+ void addImportedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets which @p schemas have been imported already, so the parser
+ * can detect circular imports.
+ */
+ void setImportedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Adds @p schemas to the list of already redefined schemas, so the parser
+ * can detect multiple redefines of the same schema.
+ */
+ void addRedefinedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets which @p schemas have been redefined already, so the parser
+ * can detect multiple redefines of the same schema.
+ */
+ void setRedefinedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets the target namespace of the schema to parse.
+ */
+ void setTargetNamespace(const QString &targetNamespace);
+
+ /**
+ * Sets the document URI of the schema to parse.
+ */
+ void setDocumentURI(const QUrl &uri);
+
+ /**
+ * Returns the document URI of the schema to parse.
+ */
+ QUrl documentURI() const;
+
+ /**
+ * Reimplemented from MaintainingReader, always returns @c false.
+ */
+ bool isAnyAttributeAllowed() const;
+
+ private:
+ /**
+ * Used internally to report any kind of parsing error or
+ * schema inconsistency.
+ */
+ virtual void error(const QString &msg);
+
+ void attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type = SchemaType::Ptr());
+
+ /**
+ * Sets the target namespace of the schema to parse.
+ */
+ void setTargetNamespaceExtended(const QString &targetNamespace);
+
+ /**
+ * This method is called for parsing the top-level <em>schema</em> object.
+ */
+ void parseSchema(ParserType parserType);
+
+ /**
+ * This method is called for parsing any top-level <em>include</em> object.
+ */
+ void parseInclude();
+
+ /**
+ * This method is called for parsing any top-level <em>import</em> object.
+ */
+ void parseImport();
+
+ /**
+ * This method is called for parsing any top-level <em>redefine</em> object.
+ */
+ void parseRedefine();
+
+ /**
+ * This method is called for parsing any <em>annotation</em> object everywhere
+ * in the schema.
+ */
+ XsdAnnotation::Ptr parseAnnotation();
+
+ /**
+ * This method is called for parsing an <em>appinfo</em> object as child of
+ * an <em>annotation</em> object.
+ */
+ XsdApplicationInformation::Ptr parseAppInfo();
+
+ /**
+ * This method is called for parsing a <em>documentation</em> object as child of
+ * an <em>annotation</em> object.
+ */
+ XsdDocumentation::Ptr parseDocumentation();
+
+ /**
+ * This method is called for parsing a <em>defaultOpenContent</em> object.
+ */
+ void parseDefaultOpenContent();
+
+ /**
+ * This method is called for parsing any top-level <em>simpleType</em> object.
+ */
+ XsdSimpleType::Ptr parseGlobalSimpleType();
+
+ /**
+ * This method is called for parsing any <em>simpleType</em> object as descendant
+ * of an <em>element</em> or <em>complexType</em> object.
+ */
+ XsdSimpleType::Ptr parseLocalSimpleType();
+
+ /**
+ * This method is called for parsing a <em>restriction</em> object as child
+ * of a <em>simpleType</em> object.
+ */
+ void parseSimpleRestriction(const XsdSimpleType::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>list</em> object as child
+ * of a <em>simpleType</em> object.
+ */
+ void parseList(const XsdSimpleType::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>union</em> object as child
+ * of a <em>simpleType</em> object.
+ */
+ void parseUnion(const XsdSimpleType::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>minExclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMinExclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>minInclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMinInclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>maxExclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMaxExclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>maxInclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMaxInclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>totalDigits</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseTotalDigitsFacet();
+
+ /**
+ * This method is called for parsing a <em>fractionDigits</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseFractionDigitsFacet();
+
+ /**
+ * This method is called for parsing a <em>length</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseLengthFacet();
+
+ /**
+ * This method is called for parsing a <em>minLength</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMinLengthFacet();
+
+ /**
+ * This method is called for parsing a <em>maxLength</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMaxLengthFacet();
+
+ /**
+ * This method is called for parsing an <em>enumeration</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseEnumerationFacet();
+
+ /**
+ * This method is called for parsing a <em>whiteSpace</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseWhiteSpaceFacet();
+
+ /**
+ * This method is called for parsing a <em>pattern</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parsePatternFacet();
+
+ /**
+ * This method is called for parsing an <em>assertion</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseAssertionFacet();
+
+ /**
+ * This method is called for parsing any top-level <em>complexType</em> object.
+ */
+ XsdComplexType::Ptr parseGlobalComplexType();
+
+ /**
+ * This method is called for parsing any <em>complexType</em> object as descendant
+ * of an <em>element</em> object.
+ */
+ XsdComplexType::Ptr parseLocalComplexType();
+
+ /**
+ * This method resolves the content type of the @p complexType for the given
+ * @p effectiveMixed value.
+ */
+ void resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed);
+
+ /**
+ * This method is called for parsing a <em>simpleContent</em> object as child
+ * of a <em>complexType</em> object.
+ */
+ void parseSimpleContent(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing a <em>restriction</em> object as child
+ * of a <em>simpleContent</em> object.
+ */
+ void parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing an <em>extension</em> object as child
+ * of a <em>simpleContent</em> object.
+ */
+ void parseSimpleContentExtension(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing a <em>complexContent</em> object as child
+ * of a <em>complexType</em> object.
+ *
+ * @param complexType The complex type the complex content belongs to.
+ * @param mixed The output parameter for the mixed value.
+ */
+ void parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed);
+
+ /**
+ * This method is called for parsing a <em>restriction</em> object as child
+ * of a <em>complexContent</em> object.
+ */
+ void parseComplexContentRestriction(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing an <em>extension</em> object as child
+ * of a <em>complexContent</em> object.
+ */
+ void parseComplexContentExtension(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing an <em>assert</em> object as child
+ * of a <em>complexType</em> or parsing a <em>assertion</em> facet object as
+ * child of a <em>simpleType</em>.
+ *
+ * @param nodeName Either XsdSchemaToken::Assert or XsdSchemaToken::Assertion.
+ * @param tag Either XsdTagScope::Assert or XsdTagScope::Assertion.
+ */
+ XsdAssertion::Ptr parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag);
+
+ /**
+ * This method is called for parsing an <em>openContent</em> object.
+ */
+ XsdComplexType::OpenContent::Ptr parseOpenContent();
+
+ /**
+ * This method is called for parsing a top-level <em>group</em> object.
+ */
+ XsdModelGroup::Ptr parseNamedGroup();
+
+ /**
+ * This method is called for parsing a non-top-level <em>group</em> object
+ * that contains a <em>ref</em> attribute.
+ */
+ XsdTerm::Ptr parseReferredGroup(const XsdParticle::Ptr &particle);
+
+ /**
+ * This method is called for parsing an <em>all</em> object as child
+ * of a top-level <em>group</em> object.
+ *
+ * @param parent The schema component the <em>all</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseAll(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing an <em>all</em> object as descendant
+ * of a <em>complexType</em> object.
+ *
+ * @param particle The particle the <em>all</em> object belongs to.
+ * @param parent The schema component the <em>all</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>choice</em> object as child
+ * of a top-level <em>group</em> object.
+ *
+ * @param parent The schema component the <em>choice</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseChoice(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>choice</em> object as descendant
+ * of a <em>complexType</em> object or a <em>choice</em> object.
+ *
+ * @param particle The particle the <em>choice</em> object belongs to.
+ * @param parent The schema component the <em>choice</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>sequence</em> object as child
+ * of a top-level <em>group</em> object.
+ *
+ * @param parent The schema component the <em>sequence</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseSequence(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>sequence</em> object as descendant
+ * of a <em>complexType</em> object or a <em>sequence</em> object.
+ *
+ * @param particle The particle the <em>sequence</em> object belongs to.
+ * @param parent The schema component the <em>sequence</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * A helper method that parses the minOccurs and maxOccurs constraints for
+ * the given @p particle that has the given @p tagName.
+ */
+ bool parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char* tagName);
+
+ /**
+ * This method is called for parsing any top-level <em>attribute</em> object.
+ */
+ XsdAttribute::Ptr parseGlobalAttribute();
+
+ /**
+ * This method is called for parsing any non-top-level <em>attribute</em> object as a
+ * descendant of a <em>complexType</em> object or an <em>attributeGroup</em> object.
+ *
+ * @param parent The parent component the <em>attribute</em> object is part of.
+ */
+ XsdAttributeUse::Ptr parseLocalAttribute(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a top-level <em>attributeGroup</em> object.
+ */
+ XsdAttributeGroup::Ptr parseNamedAttributeGroup();
+
+ /**
+ * This method is called for parsing a non-top-level <em>attributeGroup</em> object
+ * that contains a <em>ref</em> attribute.
+ */
+ XsdAttributeUse::Ptr parseReferredAttributeGroup();
+
+ /**
+ * This method is called for parsing any top-level <em>element</em> object.
+ */
+ XsdElement::Ptr parseGlobalElement();
+
+ /**
+ * This method is called for parsing any non-top-level <em>element</em> object as a
+ * descendant of a <em>complexType</em> object or a <em>group</em> object.
+ *
+ * @param particle The particle the <em>element</em> object belongs to.
+ * @param parent The parent component the <em>element</em> object is part of.
+ */
+ XsdTerm::Ptr parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>unique</em> object as child of an <em>element</em> object.
+ */
+ XsdIdentityConstraint::Ptr parseUnique();
+
+ /**
+ * This method is called for parsing a <em>key</em> object as child of an <em>element</em> object.
+ */
+ XsdIdentityConstraint::Ptr parseKey();
+
+ /**
+ * This method is called for parsing a <em>keyref</em> object as child of an <em>element</em> object.
+ */
+ XsdIdentityConstraint::Ptr parseKeyRef(const XsdElement::Ptr &element);
+
+ /**
+ * This method is called for parsing a <em>selector</em> object as child of an <em>unique</em> object,
+ * <em>key</em> object or <em>keyref</em> object,
+ *
+ * @param ptr The identity constraint it belongs to.
+ */
+ void parseSelector(const XsdIdentityConstraint::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>field</em> object as child of an <em>unique</em> object,
+ * <em>key</em> object or <em>keyref</em> object,
+ *
+ * @param ptr The identity constraint it belongs to.
+ */
+ void parseField(const XsdIdentityConstraint::Ptr &ptr);
+
+ /**
+ * This method is called for parsing an <em>alternative</em> object inside an <em>element</em> object.
+ */
+ XsdAlternative::Ptr parseAlternative();
+
+ /**
+ * This method is called for parsing a top-level <em>notation</em> object.
+ */
+ XsdNotation::Ptr parseNotation();
+
+ /**
+ * This method is called for parsing an <em>any</em> object somewhere in
+ * the schema.
+ *
+ * @param particle The particle the <em>any</em> object belongs to.
+ */
+ XsdWildcard::Ptr parseAny(const XsdParticle::Ptr &particle);
+
+ /**
+ * This method is called for parsing an <em>anyAttribute</em> object somewhere in
+ * the schema.
+ */
+ XsdWildcard::Ptr parseAnyAttribute();
+
+ /**
+ * This method is called for parsing unknown object as descendant of the <em>annotation</em> object.
+ */
+ void parseUnknownDocumentation();
+
+ /**
+ * This method is called for parsing unknown object in the schema.
+ */
+ void parseUnknown();
+
+ /**
+ * Returnes an source location for the current position.
+ */
+ QSourceLocation currentSourceLocation() const;
+
+ /**
+ * Converts a @p qualified name into a QXmlName @p name and does some error handling.
+ */
+ void convertName(const QString &qualified, NamespaceSupport::NameType type, QXmlName &name);
+
+ /**
+ * A helper method that reads in a 'name' attribute and checks it for syntactic errors.
+ */
+ inline QString readNameAttribute(const char *elementName);
+
+ /**
+ * A helper method that reads in an attribute that contains an QName and
+ * checks it for syntactic errors.
+ */
+ inline QString readQNameAttribute(const QString &typeAttribute, const char *elementName);
+
+ /**
+ * A helper method that reads in a namespace attribute and checks for syntactic errors.
+ */
+ inline QString readNamespaceAttribute(const QString &attributeName, const char *elementName);
+
+ /**
+ * A helper method that reads the final attribute and does correct handling of schema default definitions.
+ */
+ inline SchemaType::DerivationConstraints readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName);
+
+ /**
+ * A helper method that reads the block attribute and does correct handling of schema default definitions.
+ */
+ inline NamedSchemaComponent::BlockingConstraints readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName);
+
+ /**
+ * A helper method that reads all components for a xpath expression for the current scope.
+ */
+ XsdXPathExpression::Ptr readXPathExpression(const char *elementName);
+
+ /**
+ * Describes the type of XPath that is allowed by the readXPathAttribute method.
+ */
+ enum XPathType {
+ XPath20,
+ XPathSelector,
+ XPathField
+ };
+
+ /**
+ * A helper method that reads an attribute that represents a xpath query and does basic
+ * validation.
+ */
+ QString readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName);
+
+ /**
+ * A helper method that reads in an "id" attribute, checks it for syntactic errors
+ * and tests whether a component with the same id has already been parsed.
+ */
+ inline void validateIdAttribute(const char *elementName);
+
+ /**
+ * Adds an @p element to the schema and checks for duplicated entries.
+ */
+ void addElement(const XsdElement::Ptr &element);
+
+ /**
+ * Adds an @p attribute to the schema and checks for duplicated entries.
+ */
+ void addAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Adds a @p type to the schema and checks for duplicated entries.
+ */
+ void addType(const SchemaType::Ptr &type);
+
+ /**
+ * Adds an anonymous @p type to the schema and checks for duplicated entries.
+ */
+ void addAnonymousType(const SchemaType::Ptr &type);
+
+ /**
+ * Adds an attribute @p group to the schema and checks for duplicated entries.
+ */
+ void addAttributeGroup(const XsdAttributeGroup::Ptr &group);
+
+ /**
+ * Adds an element @p group to the schema and checks for duplicated entries.
+ */
+ void addElementGroup(const XsdModelGroup::Ptr &group);
+
+ /**
+ * Adds a @p notation to the schema and checks for duplicated entries.
+ */
+ void addNotation(const XsdNotation::Ptr &notation);
+
+ /**
+ * Adds an identity @p constraint to the schema and checks for duplicated entries.
+ */
+ void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint);
+
+ /**
+ * Adds the @p facet to the list of @p facets for @p type and checks for duplicates.
+ */
+ void addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type);
+
+ /**
+ * Sets up the state machines for validating the right occurrence of xml elements.
+ */
+ void setupStateMachines();
+
+ /**
+ * Sets up a list of names of known builtin types.
+ */
+ void setupBuiltinTypeNames();
+
+ /**
+ * Checks whether the given @p tag is equal to the given @p token and
+ * the given @p namespaceToken is the XML Schema namespace.
+ */
+ inline bool isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const;
+
+ XsdSchemaContext::Ptr m_context;
+ XsdSchemaParserContext::Ptr m_parserContext;
+ NamePool::Ptr m_namePool;
+ NamespaceSupport m_namespaceSupport;
+ XsdSchemaResolver::Ptr m_schemaResolver;
+ XsdSchema::Ptr m_schema;
+
+ QString m_targetNamespace;
+ QString m_attributeFormDefault;
+ QString m_elementFormDefault;
+ QString m_blockDefault;
+ QString m_finalDefault;
+ QString m_xpathDefaultNamespace;
+ QXmlName m_defaultAttributes;
+ XsdComplexType::OpenContent::Ptr m_defaultOpenContent;
+ bool m_defaultOpenContentAppliesToEmpty;
+
+ NamespaceSet m_includedSchemas;
+ NamespaceSet m_importedSchemas;
+ NamespaceSet m_redefinedSchemas;
+ QUrl m_documentURI;
+ XsdIdCache::Ptr m_idCache;
+ QHash<XsdTagScope::Type, XsdStateMachine<XsdSchemaToken::NodeName> > m_stateMachines;
+ ComponentLocationHash m_componentLocationHash;
+ QSet<QXmlName> m_builtinTypeNames;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp
new file mode 100644
index 0000000..47592b1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp
@@ -0,0 +1,1110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaparser_p.h"
+
+#include "qbuiltintypes_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/**
+ * @page using_dfa_for_schema Using DFA for validation of correct XML tag occurrence
+ *
+ * This page describes how to use DFAs for validating that the XML child tags of an
+ * XML parent tag occur in the right order.
+ *
+ * To validate the occurrence of XML tags one need a regular expression that describes
+ * which tags can appear how often in what context. For example the regular expression
+ * of the global <em>attribute</em> tag in XML Schema is (annotation?, simpleType?).
+ * That means the <em>attribute</em> tag can contain an <em>annotation</em> tag followed
+ * by a <em>simpleType</em> tag, or just one <em>simpleType</em> tag and even no child
+ * tag at all.
+ * So the regular expression describes some kind of language and all the various occurrences
+ * of the child tags can be seen as words of that language.
+ * We can create a DFA now, that accepts all words (and only these words) of that language
+ * and whenever we want to check if a sequence of child tags belongs to the language,
+ * we test if the sequence passes the DFA successfully.
+ *
+ * The following example shows how to create the DFA for the regular expression method
+ * above.
+ *
+ * \dotfile GlobalAttribute_diagram.dot
+ *
+ * At first we need a start state (1), that's the state the DFA is before it
+ * starts running. As our regular expression allows that there are no child tags, the
+ * start state is an end state as well (marked by the double circle).
+ * Now we fetch the first token from the XML file (let's assume it is an <em>annotation</em> tag)
+ * and check if there is an edge labled with the tag name leaving the current state of the DFA.
+ * If there is no such edge, the input doesn't fullfill the rules of the regular expression,
+ * so we throw an error. Otherwise we follow that edge and the DFA is set to the new state (2) the
+ * edge points to. Now we fetch the next token from the XML file and do the previous steps again.
+ * If there is no further input from the XML file, we check whether the DFA is in an end state and
+ * throw an error if not.
+ *
+ * So the algorithm for checking is quite simple, the whole logic is encoded in the DFA and creating
+ * one for a regular expression is sometimes not easy, however the ones for XML Schema are straight
+ * forward.
+ *
+ * <h2>Legend:</h2>
+ * \dotfile legend.dot
+ * <br>
+ *
+ * <h2>DFA for <em>all</em> tag</h2>
+ * \dotfile All_diagram.dot
+ * <br>
+ * <h2>DFA for <em>alternative</em> tag</h2>
+ * \dotfile Alternative_diagram.dot
+ * <br>
+ * <h2>DFA for <em>annotation</em> tag</h2>
+ * \dotfile Annotation_diagram.dot
+ * <br>
+ * <h2>DFA for <em>anyAttribute</em> tag</h2>
+ * \dotfile AnyAttribute_diagram.dot
+ * <br>
+ * <h2>DFA for <em>any</em> tag</h2>
+ * \dotfile Any_diagram.dot
+ * <br>
+ * <h2>DFA for <em>assert</em> tag</h2>
+ * \dotfile Assert_diagram.dot
+ * <br>
+ * <h2>DFA for <em>choice</em> tag</h2>
+ * \dotfile Choice_diagram.dot
+ * <br>
+ * <h2>DFA for <em>complexContent</em> tag</h2>
+ * \dotfile ComplexContent_diagram.dot
+ * <br>
+ * <h2>DFA for <em>extension</em> tag inside a <em>complexContent</em> tag</h2>
+ * \dotfile ComplexContentExtension_diagram.dot
+ * <br>
+ * <h2>DFA for <em>restriction</em> tag inside a <em>complexContent</em> tag</h2>
+ * \dotfile ComplexContentRestriction_diagram.dot
+ * <br>
+ * <h2>DFA for <em>defaultOpenContent</em> tag</h2>
+ * \dotfile DefaultOpenContent_diagram.dot
+ * <br>
+ * <h2>DFA for <em>enumeration</em> tag</h2>
+ * \dotfile EnumerationFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>field</em> tag</h2>
+ * \dotfile Field_diagram.dot
+ * <br>
+ * <h2>DFA for <em>fractionDigits</em> tag</h2>
+ * \dotfile FractionDigitsFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attribute</em> tag</h2>
+ * \dotfile GlobalAttribute_diagram.dot
+ * <br>
+ * <h2>DFA for <em>complexType</em> tag</h2>
+ * \dotfile GlobalComplexType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>element</em> tag</h2>
+ * \dotfile GlobalElement_diagram.dot
+ * <br>
+ * <h2>DFA for <em>simpleType</em> tag</h2>
+ * \dotfile GlobalSimpleType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>import</em> tag</h2>
+ * \dotfile Import_diagram.dot
+ * <br>
+ * <h2>DFA for <em>include</em> tag</h2>
+ * \dotfile Include_diagram.dot
+ * <br>
+ * <h2>DFA for <em>key</em> tag</h2>
+ * \dotfile Key_diagram.dot
+ * <br>
+ * <h2>DFA for <em>keyref</em> tag</h2>
+ * \dotfile KeyRef_diagram.dot
+ * <br>
+ * <h2>DFA for <em>length</em> tag</h2>
+ * \dotfile LengthFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>list</em> tag</h2>
+ * \dotfile List_diagram.dot
+ * <br>
+ * <h2>DFA for <em>all</em> tag</h2>
+ * \dotfile LocalAll_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attribute</em> tag</h2>
+ * \dotfile LocalAttribute_diagram.dot
+ * <br>
+ * <h2>DFA for <em>choice</em> tag</h2>
+ * \dotfile LocalChoice_diagram.dot
+ * <br>
+ * <h2>DFA for <em>complexType</em> tag</h2>
+ * \dotfile LocalComplexType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>element</em> tag</h2>
+ * \dotfile LocalElement_diagram.dot
+ * <br>
+ * <h2>DFA for <em>sequence</em> tag</h2>
+ * \dotfile LocalSequence_diagram.dot
+ * <br>
+ * <h2>DFA for <em>simpleType</em> tag that </h2>
+ * \dotfile LocalSimpleType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>maxExclusive</em> tag</h2>
+ * \dotfile MaxExclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>maxInclusive</em> tag</h2>
+ * \dotfile MaxInclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>maxLength</em> tag</h2>
+ * \dotfile MaxLengthFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>minExclusive</em> tag</h2>
+ * \dotfile MinExclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>minInclusive</em> tag</h2>
+ * \dotfile MinInclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>minLength</em> tag</h2>
+ * \dotfile MinLengthFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attributeGroup</em> tag without <em>ref</em> attribute</h2>
+ * \dotfile NamedAttributeGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>group</em> tag without <em>ref</em> attribute</h2>
+ * \dotfile NamedGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>notation</em> tag</h2>
+ * \dotfile Notation_diagram.dot
+ * <br>
+ * <h2>DFA for <em>override</em> tag</h2>
+ * \dotfile Override_diagram.dot
+ * <br>
+ * <h2>DFA for <em>pattern</em> tag</h2>
+ * \dotfile PatternFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>redefine</em> tag</h2>
+ * \dotfile Redefine_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attributeGroup</em> tag with <em>ref</em> attribute</h2>
+ * \dotfile ReferredAttributeGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>group</em> tag with <em>ref</em> attribute</h2>
+ * \dotfile ReferredGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>schema</em> tag</h2>
+ * \dotfile Schema_diagram.dot
+ * <br>
+ * <h2>DFA for <em>selector</em> tag</h2>
+ * \dotfile Selector_diagram.dot
+ * <br>
+ * <h2>DFA for <em>sequence</em> tag</h2>
+ * \dotfile Sequence_diagram.dot
+ * <br>
+ * <h2>DFA for <em>simpleContent</em> tag</h2>
+ * \dotfile SimpleContent_diagram.dot
+ * <br>
+ * <h2>DFA for <em>extension</em> tag inside a <em>simpleContent</em> tag</h2>
+ * \dotfile SimpleContentExtension_diagram.dot
+ * <br>
+ * <h2>DFA for <em>restriction</em> tag inside a <em>simpleContent</em> tag</h2>
+ * \dotfile SimpleContentRestriction_diagram.dot
+ * <br>
+ * <h2>DFA for <em>restriction</em> tag inside a <em>simpleType</em> tag</h2>
+ * \dotfile SimpleRestriction_diagram.dot
+ * <br>
+ * <h2>DFA for <em>totalDigits</em> tag</h2>
+ * \dotfile TotalDigitsFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>union</em> tag</h2>
+ * \dotfile Union_diagram.dot
+ * <br>
+ * <h2>DFA for <em>unique</em> tag</h2>
+ * \dotfile Unique_diagram.dot
+ * <br>
+ * <h2>DFA for <em>whiteSpace</em> tag</h2>
+ * \dotfile WhiteSpaceFacet_diagram.dot
+ */
+
+void XsdSchemaParser::setupStateMachines()
+{
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, simpleType?) : attribute
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+
+ m_stateMachines.insert(XsdTagScope::GlobalAttribute, machine);
+ m_stateMachines.insert(XsdTagScope::LocalAttribute, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, ((simpleType | complexType)?, alternative*, (unique | key | keyref)*)) : element
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s2);
+ machine.addTransition(startState, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(startState, XsdSchemaToken::Unique, s4);
+ machine.addTransition(startState, XsdSchemaToken::Key, s4);
+ machine.addTransition(startState, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s2);
+ machine.addTransition(s1, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(s1, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s1, XsdSchemaToken::Key, s4);
+ machine.addTransition(s1, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s2, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(s2, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s2, XsdSchemaToken::Key, s4);
+ machine.addTransition(s2, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s3, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(s3, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s3, XsdSchemaToken::Key, s4);
+ machine.addTransition(s3, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s4, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s4, XsdSchemaToken::Key, s4);
+ machine.addTransition(s4, XsdSchemaToken::Keyref, s4);
+
+ m_stateMachines.insert(XsdTagScope::GlobalElement, machine);
+ m_stateMachines.insert(XsdTagScope::LocalElement, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleContent | complexContent | (openContent?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*))) : complexType
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s6 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s7 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::ComplexContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::OpenContent, s3);
+ machine.addTransition(startState, XsdSchemaToken::Group, s4);
+ machine.addTransition(startState, XsdSchemaToken::All, s4);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s4);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s4);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::ComplexContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::OpenContent, s3);
+ machine.addTransition(s1, XsdSchemaToken::Group, s4);
+ machine.addTransition(s1, XsdSchemaToken::All, s4);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s4);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s4);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s3, XsdSchemaToken::Group, s4);
+ machine.addTransition(s3, XsdSchemaToken::All, s4);
+ machine.addTransition(s3, XsdSchemaToken::Choice, s4);
+ machine.addTransition(s3, XsdSchemaToken::Sequence, s4);
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s3, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s4, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s5, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s5, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s5, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s5, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s6, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s7, XsdSchemaToken::Assert, s7);
+
+ m_stateMachines.insert(XsdTagScope::GlobalComplexType, machine);
+ m_stateMachines.insert(XsdTagScope::LocalComplexType, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (restriction | extension)) : simpleContent/complexContent
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(startState, XsdSchemaToken::Extension, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(s1, XsdSchemaToken::Extension, s2);
+
+ m_stateMachines.insert(XsdTagScope::SimpleContent, machine);
+ m_stateMachines.insert(XsdTagScope::ComplexContent, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simpleContent restriction
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s6 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::Length, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(startState, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(startState, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::Length, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s1, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s1, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::Length, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s2, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s2, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s2, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::Length, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s3, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s3, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s3, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s4, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s5, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s6, XsdSchemaToken::Assert, s6);
+
+ m_stateMachines.insert(XsdTagScope::SimpleContentRestriction, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simple content extension
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s3);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s3);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s3);
+ machine.addTransition(s2, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s3, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s4, XsdSchemaToken::Assert, s4);
+
+ m_stateMachines.insert(XsdTagScope::SimpleContentExtension, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, openContent?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*)) : complex content restriction/complex content extension
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s6 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::OpenContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::Group, s3);
+ machine.addTransition(startState, XsdSchemaToken::All, s3);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s3);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s3);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s1, XsdSchemaToken::OpenContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::Group, s3);
+ machine.addTransition(s1, XsdSchemaToken::All, s3);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s3);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s3);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s2, XsdSchemaToken::Group, s3);
+ machine.addTransition(s2, XsdSchemaToken::All, s3);
+ machine.addTransition(s2, XsdSchemaToken::Choice, s3);
+ machine.addTransition(s2, XsdSchemaToken::Sequence, s3);
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s2, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s3, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s4, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s5, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s6, XsdSchemaToken::Assert, s6);
+
+ m_stateMachines.insert(XsdTagScope::ComplexContentRestriction, machine);
+ m_stateMachines.insert(XsdTagScope::ComplexContentExtension, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) : named attribute group
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s3);
+
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s3);
+
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s3);
+
+ m_stateMachines.insert(XsdTagScope::NamedAttributeGroup, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (all | choice | sequence)?) : group
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::All, s2);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s2);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::All, s2);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s2);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s2);
+
+ m_stateMachines.insert(XsdTagScope::NamedGroup, machine);
+ m_stateMachines.insert(XsdTagScope::ReferredGroup, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (element | any)*) : all
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Element, s2);
+ machine.addTransition(startState, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Element, s2);
+ machine.addTransition(s1, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s2, XsdSchemaToken::Element, s2);
+ machine.addTransition(s2, XsdSchemaToken::Any, s2);
+
+ m_stateMachines.insert(XsdTagScope::All, machine);
+ m_stateMachines.insert(XsdTagScope::LocalAll, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (element | group | choice | sequence | any)*) : choice sequence
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Element, s2);
+ machine.addTransition(startState, XsdSchemaToken::Group, s2);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s2);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s2);
+ machine.addTransition(startState, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Element, s2);
+ machine.addTransition(s1, XsdSchemaToken::Group, s2);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s2);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s2);
+ machine.addTransition(s1, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s2, XsdSchemaToken::Element, s2);
+ machine.addTransition(s2, XsdSchemaToken::Group, s2);
+ machine.addTransition(s2, XsdSchemaToken::Choice, s2);
+ machine.addTransition(s2, XsdSchemaToken::Sequence, s2);
+ machine.addTransition(s2, XsdSchemaToken::Any, s2);
+
+ m_stateMachines.insert(XsdTagScope::Choice, machine);
+ m_stateMachines.insert(XsdTagScope::LocalChoice, machine);
+ m_stateMachines.insert(XsdTagScope::Sequence, machine);
+ m_stateMachines.insert(XsdTagScope::LocalSequence, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?) : any/selector/field/notation/include/import/referred attribute group/anyAttribute/all facets/assert
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+
+ m_stateMachines.insert(XsdTagScope::Any, machine);
+ m_stateMachines.insert(XsdTagScope::Selector, machine);
+ m_stateMachines.insert(XsdTagScope::Field, machine);
+ m_stateMachines.insert(XsdTagScope::Notation, machine);
+ m_stateMachines.insert(XsdTagScope::Include, machine);
+ m_stateMachines.insert(XsdTagScope::Import, machine);
+ m_stateMachines.insert(XsdTagScope::ReferredAttributeGroup, machine);
+ m_stateMachines.insert(XsdTagScope::AnyAttribute, machine);
+ m_stateMachines.insert(XsdTagScope::MinExclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MinInclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MaxExclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MaxInclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::TotalDigitsFacet, machine);
+ m_stateMachines.insert(XsdTagScope::FractionDigitsFacet, machine);
+ m_stateMachines.insert(XsdTagScope::LengthFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MinLengthFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MaxLengthFacet, machine);
+ m_stateMachines.insert(XsdTagScope::EnumerationFacet, machine);
+ m_stateMachines.insert(XsdTagScope::WhiteSpaceFacet, machine);
+ m_stateMachines.insert(XsdTagScope::PatternFacet, machine);
+ m_stateMachines.insert(XsdTagScope::Assert, machine);
+ m_stateMachines.insert(XsdTagScope::Assertion, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (selector, field+)) : unique/key/keyref
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Selector, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Selector, s2);
+ machine.addTransition(s2, XsdSchemaToken::Field, s3);
+ machine.addTransition(s3, XsdSchemaToken::Field, s3);
+
+ m_stateMachines.insert(XsdTagScope::Unique, machine);
+ m_stateMachines.insert(XsdTagScope::Key, machine);
+ m_stateMachines.insert(XsdTagScope::KeyRef, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleType | complexType)?) : alternative
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s2);
+
+ m_stateMachines.insert(XsdTagScope::Alternative, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (appinfo | documentation)* : annotation
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Appinfo, s1);
+ machine.addTransition(startState, XsdSchemaToken::Documentation, s1);
+
+ machine.addTransition(s1, XsdSchemaToken::Appinfo, s1);
+ machine.addTransition(s1, XsdSchemaToken::Documentation, s1);
+
+ m_stateMachines.insert(XsdTagScope::Annotation, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (restriction | list | union)) : simpleType
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(startState, XsdSchemaToken::List, s2);
+ machine.addTransition(startState, XsdSchemaToken::Union, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(s1, XsdSchemaToken::List, s2);
+ machine.addTransition(s1, XsdSchemaToken::Union, s2);
+
+ m_stateMachines.insert(XsdTagScope::GlobalSimpleType, machine);
+ m_stateMachines.insert(XsdTagScope::LocalSimpleType, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)) : simple type restriction
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::Length, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(startState, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(startState, XsdSchemaToken::Assertion, s3);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::Length, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s1, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s1, XsdSchemaToken::Assertion, s3);
+
+ machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::Length, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s2, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s2, XsdSchemaToken::Assertion, s3);
+
+ machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::Length, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s3, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s3, XsdSchemaToken::Assertion, s3);
+
+ m_stateMachines.insert(XsdTagScope::SimpleRestriction, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, simpleType?) : list
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+
+ m_stateMachines.insert(XsdTagScope::List, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, simpleType*) : union
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s2, XsdSchemaToken::SimpleType, s2);
+
+ m_stateMachines.insert(XsdTagScope::Union, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for ((include | import | redefine |i override | annotation)*, (defaultOpenContent, annotation*)?, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*) : schema
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Include, s1);
+ machine.addTransition(startState, XsdSchemaToken::Import, s1);
+ machine.addTransition(startState, XsdSchemaToken::Redefine, s1);
+ machine.addTransition(startState, XsdSchemaToken::Override, s1);
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::DefaultOpenContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(startState, XsdSchemaToken::Group, s4);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(startState, XsdSchemaToken::Element, s4);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(startState, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s1, XsdSchemaToken::Include, s1);
+ machine.addTransition(s1, XsdSchemaToken::Import, s1);
+ machine.addTransition(s1, XsdSchemaToken::Redefine, s1);
+ machine.addTransition(s1, XsdSchemaToken::Override, s1);
+ machine.addTransition(s1, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(s1, XsdSchemaToken::DefaultOpenContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s1, XsdSchemaToken::Group, s4);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s1, XsdSchemaToken::Element, s4);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s1, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s2, XsdSchemaToken::Annotation, s3);
+ machine.addTransition(s2, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s2, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s2, XsdSchemaToken::Group, s4);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s2, XsdSchemaToken::Element, s4);
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s2, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s3, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s3, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s3, XsdSchemaToken::Group, s4);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s3, XsdSchemaToken::Element, s4);
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s3, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s4, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s4, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s4, XsdSchemaToken::Group, s4);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s4, XsdSchemaToken::Element, s4);
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s4, XsdSchemaToken::Notation, s4);
+ machine.addTransition(s4, XsdSchemaToken::Annotation, s5);
+
+ machine.addTransition(s5, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s5, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s5, XsdSchemaToken::Group, s4);
+ machine.addTransition(s5, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s5, XsdSchemaToken::Element, s4);
+ machine.addTransition(s5, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s5, XsdSchemaToken::Notation, s4);
+ machine.addTransition(s5, XsdSchemaToken::Annotation, s5);
+
+ m_stateMachines.insert(XsdTagScope::Schema, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, any) : defaultOpenContent
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Any, s2);
+
+ m_stateMachines.insert(XsdTagScope::DefaultOpenContent, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup))* : redefine
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(startState, XsdSchemaToken::Group, s1);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s1);
+
+ machine.addTransition(s1, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(s1, XsdSchemaToken::Group, s1);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s1);
+
+ m_stateMachines.insert(XsdTagScope::Redefine, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup | element | attribute | notation))* : override
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(startState, XsdSchemaToken::Group, s1);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s1);
+ machine.addTransition(startState, XsdSchemaToken::Element, s1);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s1);
+ machine.addTransition(startState, XsdSchemaToken::Notation, s1);
+
+ machine.addTransition(s1, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(s1, XsdSchemaToken::Group, s1);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s1);
+ machine.addTransition(s1, XsdSchemaToken::Element, s1);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s1);
+ machine.addTransition(s1, XsdSchemaToken::Notation, s1);
+
+ m_stateMachines.insert(XsdTagScope::Override, machine);
+ }
+}
+
+void XsdSchemaParser::setupBuiltinTypeNames()
+{
+ m_builtinTypeNames.reserve(48);
+
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnyType->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnySimpleType->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUntyped->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnyAtomicType->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUntypedAtomic->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDateTime->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDate->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsTime->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDuration->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsYearMonthDuration->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDayTimeDuration->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsFloat->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDouble->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDecimal->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNonPositiveInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNegativeInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsLong->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsInt->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsShort->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsByte->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNonNegativeInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedLong->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedInt->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedShort->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedByte->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsPositiveInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGYearMonth->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGYear->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGMonthDay->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGDay->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGMonth->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsBoolean->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsBase64Binary->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsHexBinary->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnyURI->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsQName->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsString->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNormalizedString->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsToken->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsLanguage->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNMTOKEN->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsName->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNCName->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsID->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsIDREF->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsENTITY->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNOTATION->name(m_namePool));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp
new file mode 100644
index 0000000..381d4d0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp
@@ -0,0 +1,603 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaparsercontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaParserContext::XsdSchemaParserContext(const NamePool::Ptr &namePool, const XsdSchemaContext::Ptr &context)
+ : m_namePool(namePool)
+ , m_schema(new XsdSchema(m_namePool))
+ , m_checker(new XsdSchemaChecker(context, this))
+ , m_resolver(new XsdSchemaResolver(context, this))
+ , m_elementDescriptions(setupElementDescriptions())
+{
+}
+
+NamePool::Ptr XsdSchemaParserContext::namePool() const
+{
+ return m_namePool;
+}
+
+XsdSchemaResolver::Ptr XsdSchemaParserContext::resolver() const
+{
+ return m_resolver;
+}
+
+XsdSchemaChecker::Ptr XsdSchemaParserContext::checker() const
+{
+ return m_checker;
+}
+
+XsdSchema::Ptr XsdSchemaParserContext::schema() const
+{
+ return m_schema;
+}
+
+ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash XsdSchemaParserContext::elementDescriptions() const
+{
+ return m_elementDescriptions;
+}
+
+QXmlName XsdSchemaParserContext::createAnonymousName(const QString &targetNamespace) const
+{
+ m_anonymousNameCounter.ref();
+
+ const QString name = QString::fromLatin1("__AnonymousClass_%1").arg((int)m_anonymousNameCounter);
+
+ return m_namePool->allocateQName(targetNamespace, name);
+}
+
+ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash XsdSchemaParserContext::setupElementDescriptions()
+{
+ enum
+ {
+ ReservedForElements = 60
+ };
+
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash elementDescriptions;
+ elementDescriptions.reserve(ReservedForElements);
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Schema];
+ description.optionalAttributes.reserve(10);
+ //description.tagToken = XsdSchemaToken::Schema;
+ description.optionalAttributes.insert(XsdSchemaToken::AttributeFormDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::BlockDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::DefaultAttributes);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::ElementFormDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::FinalDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::TargetNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::Version);
+ description.optionalAttributes.insert(XsdSchemaToken::XmlLanguage);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Include];
+ //description.tagToken = XsdSchemaToken::Include;
+ description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Import];
+ //description.tagToken = XsdSchemaToken::Import;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Namespace);
+ description.optionalAttributes.insert(XsdSchemaToken::SchemaLocation);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Redefine];
+ //description.tagToken = XsdSchemaToken::Redefine;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Override];
+ //description.tagToken = XsdSchemaToken::Override;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Annotation];
+ //description.tagToken = XsdSchemaToken::Annotation;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::AppInfo];
+ //description.tagToken = XsdSchemaToken::Appinfo;
+ description.optionalAttributes.insert(XsdSchemaToken::Source);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Documentation];
+ //description.tagToken = XsdSchemaToken::Documentation;
+ description.optionalAttributes.insert(XsdSchemaToken::Source);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalSimpleType];
+ //description.tagToken = XsdSchemaToken::SimpleType;
+ description.optionalAttributes.insert(XsdSchemaToken::Final);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalSimpleType];
+ //description.tagToken = XsdSchemaToken::SimpleType;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleRestriction];
+ //description.tagToken = XsdSchemaToken::Restriction;
+ description.optionalAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::List];
+ //description.tagToken = XsdSchemaToken::List;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::ItemType);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Union];
+ //description.tagToken = XsdSchemaToken::Union;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MemberTypes);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MinExclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MinExclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MinInclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MinInclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MaxExclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MaxExclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MaxInclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MaxInclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::TotalDigitsFacet];
+ //description.tagToken = XsdSchemaToken::TotalDigits;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::FractionDigitsFacet];
+ //description.tagToken = XsdSchemaToken::FractionDigits;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LengthFacet];
+ //description.tagToken = XsdSchemaToken::Length;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MinLengthFacet];
+ //description.tagToken = XsdSchemaToken::MinLength;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MaxLengthFacet];
+ //description.tagToken = XsdSchemaToken::MaxLength;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::EnumerationFacet];
+ //description.tagToken = XsdSchemaToken::Enumeration;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::WhiteSpaceFacet];
+ //description.tagToken = XsdSchemaToken::WhiteSpace;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::PatternFacet];
+ //description.tagToken = XsdSchemaToken::Pattern;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalComplexType];
+ description.optionalAttributes.reserve(7);
+ //description.tagToken = XsdSchemaToken::ComplexType;
+ description.optionalAttributes.insert(XsdSchemaToken::Abstract);
+ description.optionalAttributes.insert(XsdSchemaToken::Block);
+ description.optionalAttributes.insert(XsdSchemaToken::DefaultAttributesApply);
+ description.optionalAttributes.insert(XsdSchemaToken::Final);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mixed);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalComplexType];
+ //description.tagToken = XsdSchemaToken::ComplexType;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mixed);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleContent];
+ //description.tagToken = XsdSchemaToken::SimpleContent;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleContentRestriction];
+ //description.tagToken = XsdSchemaToken::Restriction;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleContentExtension];
+ //description.tagToken = XsdSchemaToken::Extension;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ComplexContent];
+ //description.tagToken = XsdSchemaToken::ComplexContent;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mixed);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ComplexContentRestriction];
+ //description.tagToken = XsdSchemaToken::Restriction;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ComplexContentExtension];
+ //description.tagToken = XsdSchemaToken::Extension;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::NamedGroup];
+ //description.tagToken = XsdSchemaToken::Group;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ReferredGroup];
+ description.optionalAttributes.reserve(4);
+ //description.tagToken = XsdSchemaToken::Group;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ description.requiredAttributes.insert(XsdSchemaToken::Ref);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::All];
+ //description.tagToken = XsdSchemaToken::All;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalAll];
+ //description.tagToken = XsdSchemaToken::All;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Choice];
+ //description.tagToken = XsdSchemaToken::Choice;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalChoice];
+ //description.tagToken = XsdSchemaToken::Choice;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Sequence];
+ //description.tagToken = XsdSchemaToken::Sequence;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalSequence];
+ //description.tagToken = XsdSchemaToken::Sequence;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalAttribute];
+ description.optionalAttributes.reserve(5);
+ //description.tagToken = XsdSchemaToken::Attribute;
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalAttribute];
+ description.optionalAttributes.reserve(8);
+ //description.tagToken = XsdSchemaToken::Attribute;
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Form);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Ref);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ description.optionalAttributes.insert(XsdSchemaToken::Use);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::NamedAttributeGroup];
+ //description.tagToken = XsdSchemaToken::AttributeGroup;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ReferredAttributeGroup];
+ //description.tagToken = XsdSchemaToken::AttributeGroup;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Ref);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalElement];
+ description.optionalAttributes.reserve(11);
+ //description.tagToken = XsdSchemaToken::Element;
+ description.optionalAttributes.insert(XsdSchemaToken::Block);
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Form);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Nillable);
+ description.optionalAttributes.insert(XsdSchemaToken::Ref);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalElement];
+ description.optionalAttributes.reserve(10);
+ //description.tagToken = XsdSchemaToken::Element;
+ description.optionalAttributes.insert(XsdSchemaToken::Abstract);
+ description.optionalAttributes.insert(XsdSchemaToken::Block);
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Final);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Nillable);
+ description.optionalAttributes.insert(XsdSchemaToken::SubstitutionGroup);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Unique];
+ //description.tagToken = XsdSchemaToken::Unique;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Key];
+ //description.tagToken = XsdSchemaToken::Key;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::KeyRef];
+ //description.tagToken = XsdSchemaToken::Keyref;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.requiredAttributes.insert(XsdSchemaToken::Refer);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Selector];
+ //description.tagToken = XsdSchemaToken::Selector;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Xpath);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Field];
+ //description.tagToken = XsdSchemaToken::Field;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Xpath);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Notation];
+ description.optionalAttributes.reserve(4);
+ //description.tagToken = XsdSchemaToken::Notation;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Public);
+ description.optionalAttributes.insert(XsdSchemaToken::System);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Any];
+ description.optionalAttributes.reserve(7);
+ //description.tagToken = XsdSchemaToken::Any;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::Namespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotQName);
+ description.optionalAttributes.insert(XsdSchemaToken::ProcessContents);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::AnyAttribute];
+ description.optionalAttributes.reserve(5);
+ //description.tagToken = XsdSchemaToken::AnyAttribute;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Namespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotQName);
+ description.optionalAttributes.insert(XsdSchemaToken::ProcessContents);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Alternative];
+ //description.tagToken = XsdSchemaToken::Alternative;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Test);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::OpenContent];
+ //description.tagToken = XsdSchemaToken::OpenContent;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mode);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::DefaultOpenContent];
+ //description.tagToken = XsdSchemaToken::DefaultOpenContent;
+ description.optionalAttributes.insert(XsdSchemaToken::AppliesToEmpty);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mode);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Assert];
+ //description.tagToken = XsdSchemaToken::Assert;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Test);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Assertion];
+ //description.tagToken = XsdSchemaToken::Assertion;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Test);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ Q_ASSERT_X(elementDescriptions.count() == ReservedForElements, Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("Expected is %1, actual is %2.").arg(ReservedForElements).arg(elementDescriptions.count())));
+
+ return elementDescriptions;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h
new file mode 100644
index 0000000..19c516a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaParserContext_H
+#define Patternist_XsdSchemaParserContext_H
+
+#include "qmaintainingreader_p.h" // for definition of ElementDescription
+#include "qxsdschematoken_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdschemachecker_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemaresolver_p.h"
+
+#include <QtCore/QSharedData>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A namespace class that contains identifiers for the different
+ * scopes a tag from the xml schema spec can appear in.
+ */
+ class XsdTagScope
+ {
+ public:
+ enum Type
+ {
+ Schema,
+ Include,
+ Import,
+ Redefine,
+ Annotation,
+ AppInfo,
+ Documentation,
+ GlobalSimpleType,
+ LocalSimpleType,
+ SimpleRestriction,
+ List,
+ Union,
+ MinExclusiveFacet,
+ MinInclusiveFacet,
+ MaxExclusiveFacet,
+ MaxInclusiveFacet,
+ TotalDigitsFacet,
+ FractionDigitsFacet,
+ LengthFacet,
+ MinLengthFacet,
+ MaxLengthFacet,
+ EnumerationFacet,
+ WhiteSpaceFacet,
+ PatternFacet,
+ GlobalComplexType,
+ LocalComplexType,
+ SimpleContent,
+ SimpleContentRestriction,
+ SimpleContentExtension,
+ ComplexContent,
+ ComplexContentRestriction,
+ ComplexContentExtension,
+ NamedGroup,
+ ReferredGroup,
+ All,
+ LocalAll,
+ Choice,
+ LocalChoice,
+ Sequence,
+ LocalSequence,
+ GlobalAttribute,
+ LocalAttribute,
+ NamedAttributeGroup,
+ ReferredAttributeGroup,
+ GlobalElement,
+ LocalElement,
+ Unique,
+ Key,
+ KeyRef,
+ Selector,
+ Field,
+ Notation,
+ Any,
+ AnyAttribute,
+ Alternative,
+ Assert,
+ Assertion,
+ OpenContent,
+ DefaultOpenContent,
+ Override
+ };
+ };
+
+ /**
+ * A hash that keeps the mapping between the single components that can appear
+ * in a schema document (e.g. elements, attributes, type definitions) and their
+ * source locations inside the document.
+ */
+ typedef QHash<NamedSchemaComponent::Ptr, QSourceLocation> ComponentLocationHash;
+
+ /**
+ * @short A context for schema parsing.
+ *
+ * This class provides a context for all components that are
+ * nedded for parsing and compiling the XML schema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaParserContext : public QSharedData
+ {
+ public:
+ /**
+ * A smart pointer wrapping XsdSchemaParserContext instances.
+ */
+ typedef QExplicitlySharedDataPointer<XsdSchemaParserContext> Ptr;
+
+ /**
+ * Creates a new schema parser context object.
+ *
+ * @param namePool The name pool where all names of the schema will be stored in.
+ * @param context The schema context to use for error reporting etc.
+ */
+ XsdSchemaParserContext(const NamePool::Ptr &namePool, const XsdSchemaContext::Ptr &context);
+
+ /**
+ * Returns the name pool of the schema parser context.
+ */
+ NamePool::Ptr namePool() const;
+
+ /**
+ * Returns the schema resolver of the schema context.
+ */
+ XsdSchemaResolver::Ptr resolver() const;
+
+ /**
+ * Returns the schema resolver of the schema context.
+ */
+ XsdSchemaChecker::Ptr checker() const;
+
+ /**
+ * Returns the schema object of the schema context.
+ */
+ XsdSchema::Ptr schema() const;
+
+ /**
+ * Returns the element descriptions for the schema parser.
+ *
+ * The element descriptions are a fast lookup table for
+ * verifying whether certain attributes are allowed for
+ * a given element type.
+ */
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash elementDescriptions() const;
+
+ /**
+ * Returns an unique name that is used by the schema parser
+ * for anonymous types.
+ *
+ * @param targetNamespace The namespace of the name.
+ */
+ QXmlName createAnonymousName(const QString &targetNamespace) const;
+
+ private:
+ /**
+ * Fills the element description hash with the required and prohibited
+ * attributes.
+ */
+ static ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash setupElementDescriptions();
+
+ NamePool::Ptr m_namePool;
+ XsdSchema::Ptr m_schema;
+ XsdSchemaChecker::Ptr m_checker;
+ XsdSchemaResolver::Ptr m_resolver;
+ const ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash m_elementDescriptions;
+ mutable QAtomicInt m_anonymousNameCounter;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemaresolver.cpp b/src/xmlpatterns/schema/qxsdschemaresolver.cpp
new file mode 100644
index 0000000..f3d1ed0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaresolver.cpp
@@ -0,0 +1,1743 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaresolver_p.h"
+
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qqnamevalue_p.h"
+#include "qxsdattributereference_p.h"
+#include "qxsdparticlechecker_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemaparsercontext_p.h"
+#include "qxsdschematypesfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaResolver::XsdSchemaResolver(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext)
+ : m_context(context)
+ , m_checker(parserContext->checker())
+ , m_namePool(parserContext->namePool())
+ , m_schema(parserContext->schema())
+{
+ m_keyReferences.reserve(20);
+ m_simpleRestrictionBases.reserve(20);
+ m_simpleListTypes.reserve(20);
+ m_simpleUnionTypes.reserve(20);
+ m_elementTypes.reserve(20);
+ m_complexBaseTypes.reserve(20);
+ m_attributeTypes.reserve(20);
+ m_alternativeTypes.reserve(20);
+ m_alternativeTypeElements.reserve(20);
+ m_substitutionGroupAffiliations.reserve(20);
+
+ m_predefinedSchemaTypes = m_context->schemaTypeFactory()->types().values();
+}
+
+XsdSchemaResolver::~XsdSchemaResolver()
+{
+}
+
+void XsdSchemaResolver::resolve()
+{
+ m_checker->addComponentLocationHash(m_componentLocationHash);
+
+ // resolve the base types for all types
+ resolveSimpleRestrictionBaseTypes();
+ resolveComplexBaseTypes();
+
+ // do the basic checks which depend on having a base type available
+ m_checker->basicCheck();
+
+ // resolve further types that only map a type name to a type object
+ resolveSimpleListType();
+ resolveSimpleUnionTypes();
+ resolveElementTypes();
+ resolveAttributeTypes();
+ resolveAlternativeTypes();
+
+ // resolve objects that do not need information about inheritance
+ resolveKeyReferences();
+ resolveSubstitutionGroupAffiliations();
+
+ // resolve objects that do need information about inheritance
+ resolveSimpleRestrictions();
+ resolveSimpleContentComplexTypes();
+
+ // resolve objects which replace place holders
+ resolveTermReferences();
+ resolveAttributeTermReferences();
+
+ // resolve additional objects that do need information about inheritance
+ resolveAttributeInheritance();
+ resolveComplexContentComplexTypes();
+ resolveSubstitutionGroups();
+
+ resolveEnumerationFacetValues();
+
+ checkRedefinedGroups();
+ checkRedefinedAttributeGroups();
+
+ // check the constraining facets before we resolve them
+ m_checker->checkConstrainingFacets();
+
+ // add it again, as we may have added new components in the meantime
+ m_checker->addComponentLocationHash(m_componentLocationHash);
+
+ m_checker->check();
+}
+
+void XsdSchemaResolver::addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &reference, const QSourceLocation &location)
+{
+ KeyReference item;
+ item.element = element;
+ item.keyRef = keyRef;
+ item.reference = reference;
+ item.location = location;
+
+ m_keyReferences.append(item);
+}
+
+void XsdSchemaResolver::addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location)
+{
+ SimpleRestrictionBase item;
+ item.simpleType = simpleType;
+ item.baseName = baseName;
+ item.location = location;
+
+ m_simpleRestrictionBases.append(item);
+}
+
+void XsdSchemaResolver::removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type)
+{
+ for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) {
+ if (m_simpleRestrictionBases.at(i).simpleType == type) {
+ m_simpleRestrictionBases.remove(i);
+ break;
+ }
+ }
+}
+
+void XsdSchemaResolver::addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location)
+{
+ SimpleListType item;
+ item.simpleType = simpleType;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_simpleListTypes.append(item);
+}
+
+void XsdSchemaResolver::addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList<QXmlName> &typeNames, const QSourceLocation &location)
+{
+ SimpleUnionType item;
+ item.simpleType = simpleType;
+ item.typeNames = typeNames;
+ item.location = location;
+
+ m_simpleUnionTypes.append(item);
+}
+
+void XsdSchemaResolver::addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location)
+{
+ ElementType item;
+ item.element = element;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_elementTypes.append(item);
+}
+
+void XsdSchemaResolver::addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets)
+{
+ ComplexBaseType item;
+ item.complexType = complexType;
+ item.baseName = baseName;
+ item.location = location;
+ item.facets = facets;
+
+ m_complexBaseTypes.append(item);
+}
+
+void XsdSchemaResolver::removeComplexBaseType(const XsdComplexType::Ptr &type)
+{
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ if (m_complexBaseTypes.at(i).complexType == type) {
+ m_complexBaseTypes.remove(i);
+ break;
+ }
+ }
+}
+
+void XsdSchemaResolver::addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed)
+{
+ ComplexContentType item;
+ item.complexType = complexType;
+ item.explicitContent = content;
+ item.effectiveMixed = mixed;
+ m_complexContentTypes.append(item);
+}
+
+void XsdSchemaResolver::addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location)
+{
+ AttributeType item;
+ item.attribute = attribute;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_attributeTypes.append(item);
+}
+
+void XsdSchemaResolver::addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location)
+{
+ AlternativeType item;
+ item.alternative = alternative;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_alternativeTypes.append(item);
+}
+
+void XsdSchemaResolver::addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element)
+{
+ AlternativeTypeElement item;
+ item.alternative = alternative;
+ item.element = element;
+
+ m_alternativeTypeElements.append(item);
+}
+
+void XsdSchemaResolver::addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList<QXmlName> &elementNames, const QSourceLocation &location)
+{
+ SubstitutionGroupAffiliation item;
+ item.element = element;
+ item.elementNames = elementNames;
+ item.location = location;
+
+ m_substitutionGroupAffiliations.append(item);
+}
+
+void XsdSchemaResolver::addSubstitutionGroupType(const XsdElement::Ptr &element)
+{
+ m_substitutionGroupTypes.append(element);
+}
+
+void XsdSchemaResolver::addComponentLocationHash(const ComponentLocationHash &hash)
+{
+ m_componentLocationHash.unite(hash);
+}
+
+void XsdSchemaResolver::addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport)
+{
+ m_enumerationFacetValues.insert(facetValue, namespaceSupport);
+}
+
+void XsdSchemaResolver::addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group)
+{
+ RedefinedGroups item;
+ item.redefinedGroup = redefinedGroup;
+ item.group = group;
+
+ m_redefinedGroups.append(item);
+}
+
+void XsdSchemaResolver::addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group)
+{
+ RedefinedAttributeGroups item;
+ item.redefinedGroup = redefinedGroup;
+ item.group = group;
+
+ m_redefinedAttributeGroups.append(item);
+}
+
+void XsdSchemaResolver::addAllGroupCheck(const XsdReference::Ptr &reference)
+{
+ m_allGroups.insert(reference);
+}
+
+void XsdSchemaResolver::copyDataTo(const XsdSchemaResolver::Ptr &other) const
+{
+ other->m_keyReferences << m_keyReferences;
+ other->m_simpleRestrictionBases << m_simpleRestrictionBases;
+ other->m_simpleListTypes << m_simpleListTypes;
+ other->m_simpleUnionTypes << m_simpleUnionTypes;
+ other->m_elementTypes << m_elementTypes;
+ other->m_complexBaseTypes << m_complexBaseTypes;
+ other->m_complexContentTypes << m_complexContentTypes;
+ other->m_attributeTypes << m_attributeTypes;
+ other->m_alternativeTypes << m_alternativeTypes;
+ other->m_alternativeTypeElements << m_alternativeTypeElements;
+ other->m_substitutionGroupAffiliations << m_substitutionGroupAffiliations;
+ other->m_substitutionGroupTypes << m_substitutionGroupTypes;
+}
+
+QXmlName XsdSchemaResolver::baseTypeNameOfType(const SchemaType::Ptr &type) const
+{
+ for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) {
+ if (m_simpleRestrictionBases.at(i).simpleType == type)
+ return m_simpleRestrictionBases.at(i).baseName;
+ }
+
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ if (m_complexBaseTypes.at(i).complexType == type)
+ return m_complexBaseTypes.at(i).baseName;
+ }
+
+ return QXmlName();
+}
+
+QXmlName XsdSchemaResolver::typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const
+{
+ for (int i = 0; i < m_attributeTypes.count(); ++i) {
+ if (m_attributeTypes.at(i).attribute == attribute)
+ return m_attributeTypes.at(i).typeName;
+ }
+
+ return QXmlName();
+}
+
+void XsdSchemaResolver::setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty)
+{
+ m_defaultOpenContent = openContent;
+ m_defaultOpenContentAppliesToEmpty = appliesToEmpty;
+}
+
+void XsdSchemaResolver::resolveKeyReferences()
+{
+ for (int i = 0; i < m_keyReferences.count(); ++i) {
+ const KeyReference ref = m_keyReferences.at(i);
+
+ const XsdIdentityConstraint::Ptr constraint = m_schema->identityConstraint(ref.reference);
+ if (!constraint) {
+ m_context->error(QtXmlPatterns::tr("%1 references unknown %2 or %3 element %4.")
+ .arg(formatKeyword(ref.keyRef->displayName(m_namePool)))
+ .arg(formatElement("key"))
+ .arg(formatElement("unique"))
+ .arg(formatKeyword(m_namePool, ref.reference)),
+ XsdSchemaContext::XSDError, ref.location);
+ return;
+ }
+
+ if (constraint->category() != XsdIdentityConstraint::Key && constraint->category() != XsdIdentityConstraint::Unique) { // only key and unique can be referenced
+ m_context->error(QtXmlPatterns::tr("%1 references identity constraint %2 that is no %3 or %4 element.")
+ .arg(formatKeyword(ref.keyRef->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool, ref.reference))
+ .arg(formatElement("key"))
+ .arg(formatElement("unique")),
+ XsdSchemaContext::XSDError, ref.location);
+ return;
+ }
+
+ if (constraint->fields().count() != ref.keyRef->fields().count()) {
+ m_context->error(QtXmlPatterns::tr("%1 has a different number of fields from the identity constraint %2 that it references.")
+ .arg(formatKeyword(ref.keyRef->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool, ref.reference)),
+ XsdSchemaContext::XSDError, ref.location);
+ return;
+ }
+
+ ref.keyRef->setReferencedKey(constraint);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleRestrictionBaseTypes()
+{
+ // iterate over all simple types that are derived by restriction
+ for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) {
+ const SimpleRestrictionBase item = m_simpleRestrictionBases.at(i);
+
+ // find the base type
+ SchemaType::Ptr type = m_schema->type(item.baseName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.baseName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.baseName))
+ .arg(formatElement("restriction")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.simpleType->setWxsSuperType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleRestrictions()
+{
+ XsdSimpleType::List simpleTypes;
+
+ // first collect the global simple types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isSimpleType() && (types.at(i)->derivationMethod() == SchemaType::DerivationRestriction))
+ simpleTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isSimpleType() && (anonymousTypes.at(i)->derivationMethod() == SchemaType::DerivationRestriction))
+ simpleTypes.append(anonymousTypes.at(i));
+ }
+
+ QSet<XsdSimpleType::Ptr> visitedTypes;
+ for (int i = 0; i < simpleTypes.count(); ++i) {
+ resolveSimpleRestrictions(simpleTypes.at(i), visitedTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet<XsdSimpleType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(simpleType))
+ return;
+ else
+ visitedTypes.insert(simpleType);
+
+ if (simpleType->derivationMethod() != XsdSimpleType::DerivationRestriction)
+ return;
+
+ // as xs:NMTOKENS, xs:ENTITIES and xs:IDREFS are provided by our XsdSchemaTypesFactory, they are
+ // setup correctly already and shouldn't be handled here
+ if (m_predefinedSchemaTypes.contains(simpleType))
+ return;
+
+ const SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ Q_ASSERT(baseType);
+
+ if (baseType->isDefinedBySchema())
+ resolveSimpleRestrictions(XsdSimpleType::Ptr(baseType), visitedTypes);
+
+ simpleType->setCategory(baseType->category());
+
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ QSet<AnySimpleType::Ptr> visitedPrimitiveTypes;
+ const AnySimpleType::Ptr primitiveType = findPrimitiveType(baseType, visitedPrimitiveTypes);
+ simpleType->setPrimitiveType(primitiveType);
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ const XsdSimpleType::Ptr simpleBaseType = baseType;
+ simpleType->setItemType(simpleBaseType->itemType());
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const XsdSimpleType::Ptr simpleBaseType = baseType;
+ simpleType->setMemberTypes(simpleBaseType->memberTypes());
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleListType()
+{
+ // iterate over all simple types where the item type shall be resolved
+ for (int i = 0; i < m_simpleListTypes.count(); ++i) {
+ const SimpleListType item = m_simpleListTypes.at(i);
+
+ // try to resolve the name
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Item type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("list")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.simpleType->setItemType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleUnionTypes()
+{
+ // iterate over all simple types where the union member types shall be resolved
+ for (int i = 0; i < m_simpleUnionTypes.count(); ++i) {
+ const SimpleUnionType item = m_simpleUnionTypes.at(i);
+
+ AnySimpleType::List memberTypes;
+
+ // iterate over all union member type names
+ const QList<QXmlName> typeNames = item.typeNames;
+ for (int j = 0; j < typeNames.count(); ++j) {
+ const QXmlName typeName = typeNames.at(j);
+
+ // try to resolve the name
+ SchemaType::Ptr type = m_schema->type(typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Member type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, typeName))
+ .arg(formatElement("union")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ memberTypes.append(type);
+ }
+
+ // append the types that have been defined as <simpleType> children
+ memberTypes << item.simpleType->memberTypes();
+
+ item.simpleType->setMemberTypes(memberTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveElementTypes()
+{
+ for (int i = 0; i < m_elementTypes.count(); ++i) {
+ const ElementType item = m_elementTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("element")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.element->setType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveComplexBaseTypes()
+{
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ const ComplexBaseType item = m_complexBaseTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.baseName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.baseName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of complex type cannot be resolved.").arg(formatType(m_namePool, item.baseName)), XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ if (item.complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (type->isComplexType() && type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr baseType = type;
+ if (baseType->contentType()->variety() != XsdComplexType::ContentType::Simple) {
+ m_context->error(QtXmlPatterns::tr("%1 cannot have complex base type that has a %2.")
+ .arg(formatElement("simpleContent"))
+ .arg(formatElement("complexContent")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+ }
+
+ item.complexType->setWxsSuperType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleContentComplexTypes()
+{
+ XsdComplexType::List complexTypes;
+
+ // first collect the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema())
+ complexTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isComplexType() && anonymousTypes.at(i)->isDefinedBySchema())
+ complexTypes.append(anonymousTypes.at(i));
+ }
+
+ QSet<XsdComplexType::Ptr> visitedTypes;
+ for (int i = 0; i < complexTypes.count(); ++i) {
+ if (XsdComplexType::Ptr(complexTypes.at(i))->contentType()->variety() == XsdComplexType::ContentType::Simple)
+ resolveSimpleContentComplexTypes(complexTypes.at(i), visitedTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(complexType))
+ return;
+ else
+ visitedTypes.insert(complexType);
+
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // at this point simple types have been resolved already, so we care about
+ // complex types here only
+
+ // http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctsc
+ // 1
+ if (baseType->isComplexType() && baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType = baseType;
+
+ resolveSimpleContentComplexTypes(complexBaseType, visitedTypes);
+
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
+ if (complexType->contentType()->simpleType()) {
+ // 1.1 contains the content of the <simpleType> already
+ } else {
+ // 1.2
+ const XsdSimpleType::Ptr anonType(new XsdSimpleType());
+ XsdSimpleType::TypeCategory baseCategory = complexBaseType->contentType()->simpleType()->category();
+ anonType->setCategory(baseCategory);
+
+ if (baseCategory == XsdSimpleType::SimpleTypeList) {
+ const XsdSimpleType::Ptr baseSimpleType = complexBaseType->contentType()->simpleType();
+ anonType->setItemType(baseSimpleType->itemType());
+ }
+
+ anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ anonType->setWxsSuperType(complexBaseType->contentType()->simpleType());
+ anonType->setFacets(complexTypeFacets(complexType));
+
+ QSet<AnySimpleType::Ptr> visitedPrimitiveTypes;
+ const AnySimpleType::Ptr primitiveType = findPrimitiveType(anonType->wxsSuperType(), visitedPrimitiveTypes);
+ anonType->setPrimitiveType(primitiveType);
+
+ complexType->contentType()->setSimpleType(anonType);
+
+ m_schema->addAnonymousType(anonType);
+ m_componentLocationHash.insert(anonType, m_componentLocationHash.value(complexType));
+ }
+ } else if (complexBaseType->derivationMethod() == XsdComplexType::DerivationExtension) { // 3
+ complexType->contentType()->setSimpleType(complexBaseType->contentType()->simpleType());
+ }
+ } else if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed &&
+ complexType->derivationMethod() == XsdComplexType::DerivationRestriction &&
+ XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle())) { // 2
+ // simple type was already set in parser
+
+ const XsdSimpleType::Ptr anonType(new XsdSimpleType());
+ anonType->setCategory(complexType->contentType()->simpleType()->category());
+ anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ anonType->setWxsSuperType(complexType->contentType()->simpleType());
+ anonType->setFacets(complexTypeFacets(complexType));
+
+ QSet<AnySimpleType::Ptr> visitedPrimitiveTypes;
+ const AnySimpleType::Ptr primitiveType = findPrimitiveType(anonType->wxsSuperType(), visitedPrimitiveTypes);
+ anonType->setPrimitiveType(primitiveType);
+
+ complexType->contentType()->setSimpleType(anonType);
+
+ m_schema->addAnonymousType(anonType);
+ m_componentLocationHash.insert(anonType, m_componentLocationHash.value(complexType));
+ } else {
+ complexType->contentType()->setSimpleType(BuiltinTypes::xsAnySimpleType);
+ }
+ } else if (baseType->isSimpleType()) { // 4
+ complexType->contentType()->setSimpleType(baseType);
+ } else { // 5
+ complexType->contentType()->setSimpleType(BuiltinTypes::xsAnySimpleType);
+ }
+}
+
+void XsdSchemaResolver::resolveComplexContentComplexTypes()
+{
+ XsdComplexType::List complexTypes;
+
+ // first collect the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema())
+ complexTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isComplexType() && anonymousTypes.at(i)->isDefinedBySchema())
+ complexTypes.append(anonymousTypes.at(i));
+ }
+
+ QSet<XsdComplexType::Ptr> visitedTypes;
+ for (int i = 0; i < complexTypes.count(); ++i) {
+ if (XsdComplexType::Ptr(complexTypes.at(i))->contentType()->variety() != XsdComplexType::ContentType::Simple)
+ resolveComplexContentComplexTypes(complexTypes.at(i), visitedTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(complexType))
+ return;
+ else
+ visitedTypes.insert(complexType);
+
+ ComplexContentType item;
+ bool foundCorrespondingItem = false;
+ for (int i = 0; i < m_complexContentTypes.count(); ++i) {
+ if (m_complexContentTypes.at(i).complexType == complexType) {
+ item = m_complexContentTypes.at(i);
+ foundCorrespondingItem = true;
+ break;
+ }
+ }
+
+ if (!foundCorrespondingItem)
+ return;
+
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // at this point simple types have been resolved already, so we care about
+ // complex types here only
+ if (baseType->isComplexType() && baseType->isDefinedBySchema())
+ resolveComplexContentComplexTypes(XsdComplexType::Ptr(baseType), visitedTypes);
+
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common
+
+ // 3
+ XsdParticle::Ptr effectiveContent;
+ if (!item.explicitContent) { // 3.1
+ if (item.effectiveMixed == true) { // 3.1.1
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(1);
+ particle->setMaximumOccurs(1);
+ particle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr sequence(new XsdModelGroup());
+ sequence->setCompositor(XsdModelGroup::SequenceCompositor);
+ particle->setTerm(sequence);
+
+ effectiveContent = particle;
+ } else { // 3.1.2
+ effectiveContent = XsdParticle::Ptr();
+ }
+ } else { // 3.2
+ effectiveContent = item.explicitContent;
+ }
+
+ // 4
+ XsdComplexType::ContentType::Ptr explicitContentType(new XsdComplexType::ContentType());
+ if (item.complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { // 4.1
+ if (!effectiveContent) { // 4.1.1
+ explicitContentType->setVariety(XsdComplexType::ContentType::Empty);
+ } else { // 4.1.2
+ if (item.effectiveMixed == true)
+ explicitContentType->setVariety(XsdComplexType::ContentType::Mixed);
+ else
+ explicitContentType->setVariety(XsdComplexType::ContentType::ElementOnly);
+
+ explicitContentType->setParticle(effectiveContent);
+ }
+ } else if (item.complexType->derivationMethod() == XsdComplexType::DerivationExtension) { // 4.2
+ const SchemaType::Ptr baseType = item.complexType->wxsSuperType();
+ if (baseType->isSimpleType() || (baseType->isComplexType() && baseType->isDefinedBySchema() && (XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Empty ||
+ XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Simple))) { // 4.2.1
+ if (!effectiveContent) {
+ explicitContentType->setVariety(XsdComplexType::ContentType::Empty);
+ } else {
+ if (item.effectiveMixed == true)
+ explicitContentType->setVariety(XsdComplexType::ContentType::Mixed);
+ else
+ explicitContentType->setVariety(XsdComplexType::ContentType::ElementOnly);
+
+ explicitContentType->setParticle(effectiveContent);
+ }
+ } else if (baseType->isComplexType() && baseType->isDefinedBySchema() && (XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Mixed) && !effectiveContent) { // 4.2.2
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ explicitContentType = complexBaseType->contentType();
+ } else { // 4.2.3
+ explicitContentType->setVariety(item.effectiveMixed ? XsdComplexType::ContentType::Mixed : XsdComplexType::ContentType::ElementOnly);
+
+ XsdParticle::Ptr baseParticle;
+ if (baseType == BuiltinTypes::xsAnyType) {
+ // we need a workaround here, since the xsAnyType is no real (aka XsdComplexType) complex type...
+
+ baseParticle = XsdParticle::Ptr(new XsdParticle());
+ baseParticle->setMinimumOccurs(1);
+ baseParticle->setMaximumOccurs(1);
+ baseParticle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr group(new XsdModelGroup());
+ group->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(0);
+ particle->setMaximumOccursUnbounded(true);
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ wildcard->setProcessContents(XsdWildcard::Lax);
+
+ particle->setTerm(wildcard);
+ XsdParticle::List particles;
+ particles.append(particle);
+ group->setParticles(particles);
+ baseParticle->setTerm(group);
+ } else {
+ const XsdComplexType::Ptr complexBaseType(baseType);
+ baseParticle = complexBaseType->contentType()->particle();
+ }
+ if (baseParticle && baseParticle->term()->isModelGroup() && (XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) &&
+ (!item.explicitContent)) { // 4.2.3.1
+
+ explicitContentType->setParticle(baseParticle);
+ } else if (baseParticle && baseParticle->term()->isModelGroup() && (XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) &&
+ (effectiveContent->term()->isModelGroup() && (XsdModelGroup::Ptr(effectiveContent->term())->compositor() == XsdModelGroup::AllCompositor))) { // 4.2.3.2
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(effectiveContent->minimumOccurs());
+ particle->setMaximumOccurs(1);
+ particle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr group(new XsdModelGroup());
+ group->setCompositor(XsdModelGroup::AllCompositor);
+ XsdParticle::List particles = XsdModelGroup::Ptr(baseParticle->term())->particles();
+ particles << XsdModelGroup::Ptr(effectiveContent->term())->particles();
+ group->setParticles(particles);
+ particle->setTerm(group);
+
+ explicitContentType->setParticle(particle);
+ } else { // 4.2.3.3
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(1);
+ particle->setMaximumOccurs(1);
+ particle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr group(new XsdModelGroup());
+ group->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ if (effectiveContent && effectiveContent->term()->isModelGroup() && XsdModelGroup::Ptr(effectiveContent->term())->compositor() == XsdModelGroup::AllCompositor) {
+ m_context->error(QtXmlPatterns::tr("Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type.")
+ .arg(formatType(m_namePool, complexType)).arg(formatKeyword("all")), XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ if (baseParticle && baseParticle->term()->isModelGroup() && XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(formatKeyword("all")), XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ XsdParticle::List particles;
+ if (baseParticle)
+ particles << baseParticle;
+ if (effectiveContent)
+ particles << effectiveContent;
+ group->setParticles(particles);
+ particle->setTerm(group);
+
+ explicitContentType->setParticle(particle);
+ }
+
+ if (baseType->isDefinedBySchema()) { // xs:anyType has no open content
+ const XsdComplexType::Ptr complexBaseType(baseType);
+ explicitContentType->setOpenContent(complexBaseType->contentType()->openContent());
+ }
+ }
+ }
+
+ // 5
+ XsdComplexType::OpenContent::Ptr wildcardElement;
+ if (item.complexType->contentType()->openContent()) { // 5.1
+ wildcardElement = item.complexType->contentType()->openContent();
+ } else {
+ if (m_defaultOpenContent) { // 5.2
+ if ((explicitContentType->variety() != XsdComplexType::ContentType::Empty) || // 5.2.1
+ (explicitContentType->variety() == XsdComplexType::ContentType::Empty && m_defaultOpenContentAppliesToEmpty)) { // 5.2.2
+ wildcardElement = m_defaultOpenContent;
+ }
+ }
+ }
+
+ // 6
+ if (!wildcardElement) { // 6.1
+ item.complexType->setContentType(explicitContentType);
+ } else {
+ if (wildcardElement->mode() == XsdComplexType::OpenContent::None) { // 6.2
+ const XsdComplexType::ContentType::Ptr contentType(new XsdComplexType::ContentType());
+ contentType->setVariety(explicitContentType->variety());
+ contentType->setParticle(explicitContentType->particle());
+
+ item.complexType->setContentType(contentType);
+ } else { // 6.3
+ const XsdComplexType::ContentType::Ptr contentType(new XsdComplexType::ContentType());
+
+ if (explicitContentType->variety() == XsdComplexType::ContentType::Empty)
+ contentType->setVariety(XsdComplexType::ContentType::ElementOnly);
+ else
+ contentType->setVariety(explicitContentType->variety());
+
+ if (explicitContentType->variety() == XsdComplexType::ContentType::Empty) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(1);
+ particle->setMaximumOccurs(1);
+ const XsdModelGroup::Ptr sequence(new XsdModelGroup());
+ sequence->setCompositor(XsdModelGroup::SequenceCompositor);
+ particle->setTerm(sequence);
+ contentType->setParticle(particle);
+ } else {
+ contentType->setParticle(explicitContentType->particle());
+ }
+
+ const XsdComplexType::OpenContent::Ptr openContent(new XsdComplexType::OpenContent());
+ if (wildcardElement)
+ openContent->setMode(wildcardElement->mode());
+ else
+ openContent->setMode(XsdComplexType::OpenContent::Interleave);
+
+ if (wildcardElement)
+ openContent->setWildcard(wildcardElement->wildcard());
+
+ item.complexType->setContentType(contentType);
+ }
+ }
+}
+
+void XsdSchemaResolver::resolveAttributeTypes()
+{
+ for (int i = 0; i < m_attributeTypes.count(); ++i) {
+ const AttributeType item = m_attributeTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("attribute")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ if (!type->isSimpleType() && type->category() != SchemaType::None) {
+ m_context->error(QtXmlPatterns::tr("Type of %1 element must be a simple type, %2 is not.")
+ .arg(formatElement("attribute"))
+ .arg(formatType(m_namePool, item.typeName)),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+
+ item.attribute->setType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveAlternativeTypes()
+{
+ for (int i = 0; i < m_alternativeTypes.count(); ++i) {
+ const AlternativeType item = m_alternativeTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("alternative")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.alternative->setType(type);
+ }
+
+ for (int i = 0; i < m_alternativeTypeElements.count(); ++i) {
+ const AlternativeTypeElement item = m_alternativeTypeElements.at(i);
+ item.alternative->setType(item.element->type());
+ }
+}
+
+bool hasCircularSubstitutionGroup(const XsdElement::Ptr &current, const XsdElement::Ptr &head, const NamePool::Ptr &namePool)
+{
+ if (current == head)
+ return true;
+ else {
+ const XsdElement::List elements = current->substitutionGroupAffiliations();
+ for (int i = 0; i < elements.count(); ++i) {
+ if (hasCircularSubstitutionGroup(elements.at(i), head, namePool))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void XsdSchemaResolver::resolveSubstitutionGroupAffiliations()
+{
+ for (int i = 0; i < m_substitutionGroupAffiliations.count(); ++i) {
+ const SubstitutionGroupAffiliation item = m_substitutionGroupAffiliations.at(i);
+
+ XsdElement::List affiliations;
+ for (int j = 0; j < item.elementNames.count(); ++j) {
+ const XsdElement::Ptr element = m_schema->element(item.elementNames.at(j));
+ if (!element) {
+ m_context->error(QtXmlPatterns::tr("Substitution group %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, item.elementNames.at(j)))
+ .arg(formatElement("element")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct 5)
+ if (hasCircularSubstitutionGroup(element, item.element, m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Substitution group %1 has circular definition.").arg(formatKeyword(m_namePool, item.elementNames.at(j))), XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+
+ affiliations.append(element);
+ }
+
+ item.element->setSubstitutionGroupAffiliations(affiliations);
+ }
+
+ for (int i = 0; i < m_substitutionGroupTypes.count(); ++i) {
+ const XsdElement::Ptr element = m_substitutionGroupTypes.at(i);
+ element->setType(element->substitutionGroupAffiliations().first()->type());
+ }
+}
+
+bool isSubstGroupHeadOf(const XsdElement::Ptr &head, const XsdElement::Ptr &element, const NamePool::Ptr &namePool)
+{
+ if (head->name(namePool) == element->name(namePool))
+ return true;
+
+ const XsdElement::List affiliations = element->substitutionGroupAffiliations();
+ for (int i = 0; i < affiliations.count(); ++i) {
+ if (isSubstGroupHeadOf(head, affiliations.at(i), namePool))
+ return true;
+ }
+
+ return false;
+}
+
+void XsdSchemaResolver::resolveSubstitutionGroups()
+{
+ const XsdElement::List elements = m_schema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ const XsdElement::Ptr element = elements.at(i);
+
+ // the element is always itself in the substitution group
+ element->addSubstitutionGroup(element);
+
+ for (int j = 0; j < elements.count(); ++j) {
+ if (i == j)
+ continue;
+
+ if (isSubstGroupHeadOf(element, elements.at(j), m_namePool))
+ element->addSubstitutionGroup(elements.at(j));
+ }
+ }
+}
+
+void XsdSchemaResolver::resolveTermReferences()
+{
+ // first the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+ if (complexType->contentType()->variety() != XsdComplexType::ContentType::ElementOnly && complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed)
+ continue;
+
+ resolveTermReference(complexType->contentType()->particle(), QSet<QXmlName>());
+ }
+
+ // then all anonymous complex types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (!(anonymousTypes.at(i)->isComplexType()) || !anonymousTypes.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = anonymousTypes.at(i);
+ if (complexType->contentType()->variety() != XsdComplexType::ContentType::ElementOnly && complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed)
+ continue;
+
+ resolveTermReference(complexType->contentType()->particle(), QSet<QXmlName>());
+ }
+
+ const XsdModelGroup::List groups = m_schema->elementGroups();
+ for (int i = 0; i < groups.count(); ++i) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setTerm(groups.at(i));
+ resolveTermReference(particle, QSet<QXmlName>());
+ }
+}
+
+void XsdSchemaResolver::resolveTermReference(const XsdParticle::Ptr &particle, QSet<QXmlName> visitedGroups)
+{
+ if (!particle)
+ return;
+
+ const XsdTerm::Ptr term = particle->term();
+
+ // if it is a model group, we iterate over it recursive...
+ if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr modelGroup = term;
+ const XsdParticle::List particles = modelGroup->particles();
+
+ for (int i = 0; i < particles.count(); ++i) {
+ resolveTermReference(particles.at(i), visitedGroups);
+ }
+
+ // check for unique names of elements inside all compositor
+ if (modelGroup->compositor() != XsdModelGroup::ChoiceCompositor) {
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdParticle::Ptr particle = particles.at(i);
+ const XsdTerm::Ptr term = particle->term();
+
+ if (!(term->isElement()))
+ continue;
+
+ for (int j = 0; j < particles.count(); ++j) {
+ const XsdParticle::Ptr otherParticle = particles.at(j);
+ const XsdTerm::Ptr otherTerm = otherParticle->term();
+
+ if (otherTerm->isElement() && i != j) {
+ const XsdElement::Ptr element = term;
+ const XsdElement::Ptr otherElement = otherTerm;
+
+ if (element->name(m_namePool) == otherElement->name(m_namePool)) {
+ if (modelGroup->compositor() == XsdModelGroup::AllCompositor) {
+ m_context->error(QtXmlPatterns::tr("Duplicated element names %1 in %2 element.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(formatElement("all")),
+ XsdSchemaContext::XSDError, sourceLocation(modelGroup));
+ return;
+ } else if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) {
+ if (element->type() != otherElement->type()) { // not same variety
+ m_context->error(QtXmlPatterns::tr("Duplicated element names %1 in %2 element.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(formatElement("sequence")),
+ XsdSchemaContext::XSDError, sourceLocation(modelGroup));
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ // ...otherwise we have reached the end of recursion...
+ if (!term->isReference())
+ return;
+
+ // ...or we have reached a reference term that must be resolved
+ const XsdReference::Ptr reference = term;
+ switch (reference->type()) {
+ case XsdReference::Element:
+ {
+ const XsdElement::Ptr element = m_schema->element(reference->referenceName());
+ if (element) {
+ particle->setTerm(element);
+ } else {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("element")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ }
+ break;
+ case XsdReference::ModelGroup:
+ {
+ const XsdModelGroup::Ptr modelGroup = m_schema->elementGroup(reference->referenceName());
+ if (modelGroup) {
+ if (visitedGroups.contains(modelGroup->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Circular group reference for %1.").arg(formatKeyword(modelGroup->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ } else {
+ visitedGroups.insert(modelGroup->name(m_namePool));
+ }
+
+ particle->setTerm(modelGroup);
+
+ // start recursive iteration here as well to get all references resolved
+ const XsdParticle::List particles = modelGroup->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ resolveTermReference(particles.at(i), visitedGroups);
+ }
+
+ if (modelGroup->compositor() == XsdModelGroup::AllCompositor) {
+ if (m_allGroups.contains(reference)) {
+ m_context->error(QtXmlPatterns::tr("%1 element is not allowed in this scope").arg(formatElement("all.")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() != 1) {
+ m_context->error(QtXmlPatterns::tr("%1 element cannot have %2 attribute with value other than %3.")
+ .arg(formatElement("all"))
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatData("1")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ if (particle->minimumOccurs() != 0 && particle->minimumOccurs() != 1) {
+ m_context->error(QtXmlPatterns::tr("%1 element cannot have %2 attribute with value other than %3 or %4.")
+ .arg(formatElement("all"))
+ .arg(formatAttribute("minOccurs"))
+ .arg(formatData("0"))
+ .arg(formatData("1")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ }
+ } else {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("group")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ }
+ break;
+ }
+}
+
+void XsdSchemaResolver::resolveAttributeTermReferences()
+{
+ // first all global attribute groups
+ const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ XsdWildcard::Ptr wildcard = attributeGroups.at(i)->wildcard();
+ const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeGroups.at(i)->attributeUses(), wildcard, QSet<QXmlName>());
+ attributeGroups.at(i)->setAttributeUses(uses);
+ attributeGroups.at(i)->setWildcard(wildcard);
+ }
+
+ // then the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ XsdWildcard::Ptr wildcard = complexType->attributeWildcard();
+ const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeUses, wildcard, QSet<QXmlName>());
+ complexType->setAttributeUses(uses);
+ complexType->setAttributeWildcard(wildcard);
+ }
+
+ // and afterwards all anonymous complex types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (!(anonymousTypes.at(i)->isComplexType()) || !anonymousTypes.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = anonymousTypes.at(i);
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ XsdWildcard::Ptr wildcard = complexType->attributeWildcard();
+ const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeUses, wildcard, QSet<QXmlName>());
+ complexType->setAttributeUses(uses);
+ complexType->setAttributeWildcard(wildcard);
+ }
+}
+
+XsdAttributeUse::List XsdSchemaResolver::resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet<QXmlName> visitedAttributeGroups)
+{
+ XsdAttributeUse::List resolvedAttributeUses;
+
+ for (int i = 0; i < attributeUses.count(); ++i) {
+ const XsdAttributeUse::Ptr attributeUse = attributeUses.at(i);
+ if (attributeUse->isAttributeUse()) {
+ // it is a real attribute use, so no need to resolve it
+ resolvedAttributeUses.append(attributeUse);
+ } else if (attributeUse->isReference()) {
+ // it is just a reference, so resolve it to the real attribute use
+
+ const XsdAttributeReference::Ptr reference = attributeUse;
+ if (reference->type() == XsdAttributeReference::AttributeUse) {
+
+ // lookup the real attribute
+ const XsdAttribute::Ptr attribute = m_schema->attribute(reference->referenceName());
+ if (!attribute) {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("attribute")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ }
+
+ // if both, reference and definition have a fixed or default value set, then they must be equal
+ if (attribute->valueConstraint() && attributeUse->valueConstraint()) {
+ if (attribute->valueConstraint()->value() != attributeUse->valueConstraint()->value()) {
+ m_context->error(QtXmlPatterns::tr("%1 or %2 attribute of reference %3 does not match with the attribute declaration %4.")
+ .arg(formatAttribute("fixed"))
+ .arg(formatAttribute("default"))
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatKeyword(attribute->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ }
+ }
+
+ attributeUse->setAttribute(attribute);
+ if (!attributeUse->valueConstraint() && attribute->valueConstraint())
+ attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(attribute->valueConstraint()));
+
+ resolvedAttributeUses.append(attributeUse);
+ } else if (reference->type() == XsdAttributeReference::AttributeGroup) {
+ const XsdAttributeGroup::Ptr attributeGroup = m_schema->attributeGroup(reference->referenceName());
+ if (!attributeGroup) {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("attributeGroup")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ }
+ if (visitedAttributeGroups.contains(attributeGroup->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 has circular reference.").arg(formatKeyword(m_namePool, reference->referenceName())),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ } else {
+ visitedAttributeGroups.insert(attributeGroup->name(m_namePool));
+ }
+
+ // resolve attribute wildcards as defined in http://www.w3.org/TR/xmlschema11-1/#declare-attributeGroup-wildcard
+ XsdWildcard::Ptr childWildcard;
+ resolvedAttributeUses << resolveAttributeTermReferences(attributeGroup->attributeUses(), childWildcard, visitedAttributeGroups);
+ if (!childWildcard) {
+ if (attributeGroup->wildcard()) {
+ if (wildcard) {
+ const XsdWildcard::ProcessContents contents = wildcard->processContents();
+ wildcard = XsdSchemaHelper::wildcardIntersection(wildcard, attributeGroup->wildcard());
+ wildcard->setProcessContents(contents);
+ } else {
+ wildcard = attributeGroup->wildcard();
+ }
+ }
+ } else {
+ XsdWildcard::Ptr newWildcard;
+ if (attributeGroup->wildcard()) {
+ const XsdWildcard::ProcessContents contents = attributeGroup->wildcard()->processContents();
+ newWildcard = XsdSchemaHelper::wildcardIntersection(attributeGroup->wildcard(), childWildcard);
+ newWildcard->setProcessContents(contents);
+ } else {
+ newWildcard = childWildcard;
+ }
+
+ if (wildcard) {
+ const XsdWildcard::ProcessContents contents = wildcard->processContents();
+ wildcard = XsdSchemaHelper::wildcardIntersection(wildcard, newWildcard);
+ wildcard->setProcessContents(contents);
+ } else {
+ wildcard = newWildcard;
+ }
+ }
+ }
+ }
+ }
+
+ return resolvedAttributeUses;
+}
+
+void XsdSchemaResolver::resolveAttributeInheritance()
+{
+ // collect the global and anonymous complex types
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ QSet<XsdComplexType::Ptr> visitedTypes;
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+
+ resolveAttributeInheritance(complexType, visitedTypes);
+ }
+}
+
+bool isValidWildcardRestriction(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &baseWildcard)
+{
+ if (wildcard->namespaceConstraint()->variety() == baseWildcard->namespaceConstraint()->variety()) {
+ if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, wildcard))
+ return false;
+ }
+
+ if (wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Any &&
+ baseWildcard->namespaceConstraint()->variety() != XsdWildcard::NamespaceConstraint::Any ) {
+ return false;
+ }
+ if (baseWildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Not &&
+ wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration) {
+ if (!baseWildcard->namespaceConstraint()->namespaces().intersect(wildcard->namespaceConstraint()->namespaces()).isEmpty())
+ return false;
+ }
+ if (baseWildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration &&
+ wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration) {
+ if (!wildcard->namespaceConstraint()->namespaces().subtract(baseWildcard->namespaceConstraint()->namespaces()).isEmpty())
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Since we inherit the attributes from our base class we have to walk up in the
+ * inheritance hierarchy first and resolve the attribute inheritance top-down.
+ */
+void XsdSchemaResolver::resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(complexType))
+ return;
+ else
+ visitedTypes.insert(complexType);
+
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+ Q_ASSERT(baseType);
+
+ if (!(baseType->isComplexType()) || !baseType->isDefinedBySchema())
+ return;
+
+ const XsdComplexType::Ptr complexBaseType = baseType;
+
+ resolveAttributeInheritance(complexBaseType, visitedTypes);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.attuses
+
+ // 1 and 2 (the attribute groups have been resolved here already)
+ const XsdAttributeUse::List uses = complexBaseType->attributeUses();
+
+ if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { // 3.2
+ const XsdAttributeUse::List currentUses = complexType->attributeUses();
+
+ // 3.2.1 and 3.2.2 As we also keep the prohibited attributes as objects, the algorithm below
+ // handles both the same way
+
+ // add only these attribute uses of the base type that match one of the following criteria:
+ // 1: there is no attribute use with the same name in type
+ // 2: there is no attribute with the same name marked as prohibited in type
+ for (int j = 0; j < uses.count(); ++j) {
+ const XsdAttributeUse::Ptr use = uses.at(j);
+ bool found = false;
+ for (int k = 0; k < currentUses.count(); ++k) {
+ if (use->attribute()->name(m_namePool) == currentUses.at(k)->attribute()->name(m_namePool)) {
+ found = true;
+
+ // check if prohibited usage is violated
+ if ((use->useType() == XsdAttributeUse::ProhibitedUse) && (currentUses.at(k)->useType() != XsdAttributeUse::ProhibitedUse)) {
+ m_context->error(QtXmlPatterns::tr("%1 attribute in %2 must have %3 use like in base type %4.")
+ .arg(formatAttribute(use->attribute()->displayName(m_namePool)))
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatData("prohibited"))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ break;
+ }
+ }
+
+ if (!found && uses.at(j)->useType() != XsdAttributeUse::ProhibitedUse) {
+ complexType->addAttributeUse(uses.at(j));
+ }
+ }
+ } else if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) { // 3.1
+ QHash<QXmlName, XsdAttributeUse::Ptr> availableUses;
+
+ // fill hash with attribute uses of current type for faster lookup
+ {
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ for (int i = 0; i < attributeUses.count(); ++i) {
+ availableUses.insert(attributeUses.at(i)->attribute()->name(m_namePool), attributeUses.at(i));
+ }
+ }
+
+ // just add the attribute uses of the base type
+ for (int i = 0; i < uses.count(); ++i) {
+ const XsdAttributeUse::Ptr currentAttributeUse = uses.at(i);
+
+ // if the base type defines the attribute as prohibited but we override it in current type, then don't copy the prohibited attribute use
+ if ((currentAttributeUse->useType() == XsdAttributeUse::ProhibitedUse) && availableUses.contains(currentAttributeUse->attribute()->name(m_namePool)))
+ continue;
+
+ complexType->addAttributeUse(uses.at(i));
+ }
+ }
+
+ // handle attribute wildcards: @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.anyatt
+
+ // 1
+ const XsdWildcard::Ptr completeWildcard(complexType->attributeWildcard());
+
+ if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
+ if (complexType->wxsSuperType()->isComplexType() && complexType->wxsSuperType()->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType(complexType->wxsSuperType());
+ if (complexType->attributeWildcard()) {
+ if (complexBaseType->attributeWildcard()) {
+ if (!isValidWildcardRestriction(complexType->attributeWildcard(), complexBaseType->attributeWildcard())) {
+ m_context->error(QtXmlPatterns::tr("Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ } else {
+ m_context->error(QtXmlPatterns::tr("%1 has attribute wildcard but its base type %2 has not.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+ complexType->setAttributeWildcard(completeWildcard); // 2.1
+ } else if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) {
+ XsdWildcard::Ptr baseWildcard; // 2.2.1
+ if (complexType->wxsSuperType()->isComplexType() && complexType->wxsSuperType()->isDefinedBySchema())
+ baseWildcard = XsdComplexType::Ptr(complexType->wxsSuperType())->attributeWildcard(); // 2.2.1.1
+ else
+ baseWildcard = XsdWildcard::Ptr(); // 2.2.1.2
+
+ if (!baseWildcard) {
+ complexType->setAttributeWildcard(completeWildcard); // 2.2.2.1
+ } else if (!completeWildcard) {
+ complexType->setAttributeWildcard(baseWildcard); // 2.2.2.2
+ } else {
+ XsdWildcard::Ptr unionWildcard = XsdSchemaHelper::wildcardUnion(completeWildcard, baseWildcard);
+ if (unionWildcard) {
+ unionWildcard->setProcessContents(completeWildcard->processContents());
+ complexType->setAttributeWildcard(unionWildcard); // 2.2.2.3
+ } else {
+ m_context->error(QtXmlPatterns::tr("Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaResolver::resolveEnumerationFacetValues()
+{
+ XsdSimpleType::List simpleTypes;
+
+ // first collect the global simple types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isSimpleType())
+ simpleTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isSimpleType())
+ simpleTypes.append(anonymousTypes.at(i));
+ }
+ // process all simple types
+ for (int i = 0; i < simpleTypes.count(); ++i) {
+ const XsdSimpleType::Ptr simpleType = simpleTypes.at(i);
+
+ // we resolve the enumeration values only for xs:QName and xs:NOTATION based types
+ if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType) ||
+ BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) {
+ const XsdFacet::Hash facets = simpleType->facets();
+ if (facets.contains(XsdFacet::Enumeration)) {
+ AtomicValue::List newValues;
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List values = facet->multiValue();
+ for (int j = 0; j < values.count(); ++j) {
+ const AtomicValue::Ptr value = values.at(j);
+
+ Q_ASSERT(m_enumerationFacetValues.contains(value));
+ const NamespaceSupport support( m_enumerationFacetValues.value(value) );
+
+ const QString qualifiedName = value->as<DerivedString<TypeString> >()->stringValue();
+ if (!XPathHelper::isQName(qualifiedName)) {
+ m_context->error(QtXmlPatterns::tr("Enumeration facet contains invalid content: {%1} is not a value of type %2.")
+ .arg(formatData(qualifiedName))
+ .arg(formatType(m_namePool, BuiltinTypes::xsQName)),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ QXmlName qNameValue;
+ bool result = support.processName(qualifiedName, NamespaceSupport::ElementName, qNameValue);
+ if (!result) {
+ m_context->error(QtXmlPatterns::tr("Namespace prefix of qualified name %1 is not defined.").arg(formatData(qualifiedName)),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ newValues.append(QNameValue::fromValue(m_namePool, qNameValue));
+ }
+ facet->setMultiValue(newValues);
+ }
+ }
+ }
+}
+
+QSourceLocation XsdSchemaResolver::sourceLocation(const NamedSchemaComponent::Ptr component) const
+{
+ if (m_componentLocationHash.contains(component)) {
+ return m_componentLocationHash.value(component);
+ } else {
+ QSourceLocation location;
+ location.setLine(1);
+ location.setColumn(1);
+ location.setUri(QString::fromLatin1("dummyUri"));
+
+ return location;
+ }
+}
+
+XsdFacet::Hash XsdSchemaResolver::complexTypeFacets(const XsdComplexType::Ptr &complexType) const
+{
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ if (m_complexBaseTypes.at(i).complexType == complexType)
+ return m_complexBaseTypes.at(i).facets;
+ }
+
+ return XsdFacet::Hash();
+}
+
+void XsdSchemaResolver::checkRedefinedGroups()
+{
+ for (int i = 0; i < m_redefinedGroups.count(); ++i) {
+ const RedefinedGroups item = m_redefinedGroups.at(i);
+
+ // create dummy particles...
+ const XsdParticle::Ptr redefinedParticle(new XsdParticle());
+ redefinedParticle->setTerm(item.redefinedGroup);
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setTerm(item.group);
+
+ // so that we can pass them to XsdParticleChecker::subsumes()
+ QString errorMsg;
+ if (!XsdParticleChecker::subsumes(particle, redefinedParticle, m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("%1 element %2 is not a valid restriction of the %3 element it redefines: %4.")
+ .arg(formatElement("group"))
+ .arg(formatData(item.redefinedGroup->displayName(m_namePool)))
+ .arg(formatElement("group"))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(item.redefinedGroup));
+ return;
+ }
+ }
+}
+
+void XsdSchemaResolver::checkRedefinedAttributeGroups()
+{
+ for (int i = 0; i < m_redefinedAttributeGroups.count(); ++i) {
+ const RedefinedAttributeGroups item = m_redefinedAttributeGroups.at(i);
+
+ QString errorMsg;
+ if (!XsdSchemaHelper::isValidAttributeGroupRestriction(item.redefinedGroup, item.group, m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("%1 element %2 is not a valid restriction of the %3 element it redefines: %4.")
+ .arg(formatElement("attributeGroup"))
+ .arg(formatData(item.redefinedGroup->displayName(m_namePool)))
+ .arg(formatElement("attributeGroup"))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(item.redefinedGroup));
+ return;
+ }
+ }
+}
+
+AnySimpleType::Ptr XsdSchemaResolver::findPrimitiveType(const AnySimpleType::Ptr &type, QSet<AnySimpleType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(type)) {
+ // found invalid circular reference...
+ return AnySimpleType::Ptr();
+ } else {
+ visitedTypes.insert(type);
+ }
+
+ const QXmlName typeName = type->name(m_namePool);
+ if (typeName == BuiltinTypes::xsString->name(m_namePool) ||
+ typeName == BuiltinTypes::xsBoolean->name(m_namePool) ||
+ typeName == BuiltinTypes::xsFloat->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDouble->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDecimal->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDuration->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDateTime->name(m_namePool) ||
+ typeName == BuiltinTypes::xsTime->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDate->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGYearMonth->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGYear->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGMonthDay->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGDay->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGMonth->name(m_namePool) ||
+ typeName == BuiltinTypes::xsHexBinary->name(m_namePool) ||
+ typeName == BuiltinTypes::xsBase64Binary->name(m_namePool) ||
+ typeName == BuiltinTypes::xsAnyURI->name(m_namePool) ||
+ typeName == BuiltinTypes::xsQName->name(m_namePool) ||
+ typeName == BuiltinTypes::xsNOTATION->name(m_namePool) ||
+ typeName == BuiltinTypes::xsAnySimpleType->name(m_namePool))
+ return type;
+ else {
+ if (type->wxsSuperType())
+ return findPrimitiveType(type->wxsSuperType(), visitedTypes);
+ else {
+ return AnySimpleType::Ptr();
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaresolver_p.h b/src/xmlpatterns/schema/qxsdschemaresolver_p.h
new file mode 100644
index 0000000..ef0154b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaresolver_p.h
@@ -0,0 +1,578 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaResolver_H
+#define Patternist_XsdSchemaResolver_H
+
+#include "qnamespacesupport_p.h"
+#include "qschematype_p.h"
+#include "qschematypefactory_p.h"
+#include "qxsdalternative_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdschemachecker_p.h"
+#include "qxsdsimpletype_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class XsdSchemaContext;
+ class XsdSchemaParserContext;
+
+ /**
+ * @short Encapsulates the resolving of type/element references in a schema after parsing has finished.
+ *
+ * This class collects task for resolving types or element references. After the parsing has finished,
+ * one can start the resolve process by calling resolve().
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaResolver : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchemaResolver> Ptr;
+
+ /**
+ * Creates a new schema resolver.
+ *
+ * @param context The schema context used for error reporting etc..
+ * @param parserContext The schema parser context where all objects to resolve belong to.
+ */
+ XsdSchemaResolver(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext);
+
+ /**
+ * Destroys the schema resolver.
+ */
+ ~XsdSchemaResolver();
+
+ /**
+ * Starts the resolve process.
+ */
+ void resolve();
+
+ /**
+ * Adds a resolve task for key references.
+ *
+ * The resolver will try to set the referencedKey property of @p keyRef to the <em>key</em> or <em>unique</em> object
+ * of @p element that has the given @p name.
+ */
+ void addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &name, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the base type of restriction of a simple type.
+ *
+ * The resolver will set the base type of @p simpleType to the type named by @p baseName.
+ */
+ void addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location);
+
+ /**
+ * Removes the resolve task for the base type of restriction of the simple @p type.
+ */
+ void removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type);
+
+ /**
+ * Adds a resolve task for the list type of a simple type.
+ *
+ * The resolver will set the itemType property of @p simpleType to the type named by @p typeName.
+ */
+ void addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the member types of a simple type.
+ *
+ * The resolver will set the memberTypes property of @p simpleType to the types named by @p typeNames.
+ */
+ void addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList<QXmlName> &typeNames, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the type of an element.
+ *
+ * The resolver will set the type of the @p element to the type named by @p typeName.
+ */
+ void addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the base type of a complex type.
+ *
+ * The resolver will set the base type of @p complexType to the type named by @p baseName.
+ */
+ void addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets = XsdFacet::Hash());
+
+ /**
+ * Removes the resolve task for the base type of the complex @p type.
+ */
+ void removeComplexBaseType(const XsdComplexType::Ptr &type);
+
+ /**
+ * Adds a resolve task for the content type of a complex type.
+ *
+ * The resolver will set the content type properties for @p complexType based on the
+ * given explicit @p content and effective @p mixed value.
+ */
+ void addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed);
+
+ /**
+ * Adds a resolve task for the type of an attribute.
+ *
+ * The resolver will set the type of the @p attribute to the type named by @p typeName.
+ */
+ void addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the type of an alternative.
+ *
+ * The resolver will set the type of the @p alternative to the type named by @p typeName.
+ */
+ void addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the type of an alternative.
+ *
+ * The resolver will set the type of the @p alternative to the type of the @p element after
+ * the type of the @p element has been resolved.
+ */
+ void addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element);
+
+ /**
+ * Adds a resolve task for the substituion group affiliations of an element.
+ *
+ * The resolver will set the substitution group affiliations of the @p element to the
+ * top-level element named by @p elementNames.
+ */
+ void addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList<QXmlName> &elementName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for an element that has no type specified, only a substitution group
+ * affiliation.
+ *
+ * The resolver will set the type of the substitution group affiliation as type for the element.
+ */
+ void addSubstitutionGroupType(const XsdElement::Ptr &element);
+
+ /**
+ * Adds the component location hash, so the resolver is able to report meaning full
+ * error messages.
+ */
+ void addComponentLocationHash(const QHash<NamedSchemaComponent::Ptr, QSourceLocation> &hash);
+
+ /**
+ * Add a resolve task for enumeration facet values.
+ *
+ * In case the enumeration is of type QName or NOTATION, we have to resolve the QName later,
+ * so we store the namespace bindings together with the facet value here and resolve it as soon as
+ * we have all type information available.
+ */
+ void addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport);
+
+ /**
+ * Add a check job for redefined groups.
+ *
+ * When an element group is redefined, we have to check whether the redefined group is a valid
+ * restriction of the group it redefines. As we need all type information for that, we keep them
+ * here for later checking.
+ */
+ void addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group);
+
+ /**
+ * Add a check job for redefined attribute groups.
+ *
+ * When an attribute group is redefined, we have to check whether the redefined group is a valid
+ * restriction of the group it redefines. As we need all type information for that, we keep them
+ * here for later checking.
+ */
+ void addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group);
+
+ /**
+ * Adds a check for nested <em>all</em> groups.
+ */
+ void addAllGroupCheck(const XsdReference::Ptr &reference);
+
+ /**
+ * Copies the data to resolve to an @p other resolver.
+ *
+ * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
+ */
+ void copyDataTo(const XsdSchemaResolver::Ptr &other) const;
+
+ /**
+ * Returns the to resolve base type name for the given @p type.
+ *
+ * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
+ */
+ QXmlName baseTypeNameOfType(const SchemaType::Ptr &type) const;
+
+ /**
+ * Returns the to resolve type name for the given @p attribute.
+ *
+ * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
+ */
+ QXmlName typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const;
+
+ /**
+ * Sets the defaultOpenContent object from the schema parser.
+ */
+ void setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty);
+
+ private:
+ /**
+ * Resolves key references.
+ */
+ void resolveKeyReferences();
+
+ /**
+ * Resolves the base types of simple types derived by restriction.
+ */
+ void resolveSimpleRestrictionBaseTypes();
+
+ /**
+ * Resolves the other properties except the base type
+ * of all simple restrictions.
+ */
+ void resolveSimpleRestrictions();
+
+ /**
+ * Resolves the other properties except the base type
+ * of the given simple restriction.
+ *
+ * @param simpleType The restricted type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ */
+ void resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet<XsdSimpleType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves the item type property of simple types derived by list.
+ */
+ void resolveSimpleListType();
+
+ /**
+ * Resolves the member types property of simple types derived by union.
+ */
+ void resolveSimpleUnionTypes();
+
+ /**
+ * Resolves element types.
+ */
+ void resolveElementTypes();
+
+ /**
+ * Resolves base type of complex types.
+ */
+ void resolveComplexBaseTypes();
+
+ /**
+ * Resolves the simple content model of a complex type
+ * depending on its base type.
+ */
+ void resolveSimpleContentComplexTypes();
+
+ /**
+ * Resolves the complex content model of a complex type
+ * depending on its base type.
+ */
+ void resolveComplexContentComplexTypes();
+
+ /**
+ * Resolves the simple content model of a complex type
+ * depending on its base type.
+ *
+ * @param complexType The complex type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ */
+ void resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves the complex content model of a complex type
+ * depending on its base type.
+ *
+ * @param complexType The complex type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ */
+ void resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves attribute types.
+ */
+ void resolveAttributeTypes();
+
+ /**
+ * Resolves alternative types.
+ */
+ void resolveAlternativeTypes();
+
+ /**
+ * Resolves substitution group affiliations.
+ */
+ void resolveSubstitutionGroupAffiliations();
+
+ /**
+ * Resolves substitution groups.
+ */
+ void resolveSubstitutionGroups();
+
+ /**
+ * Resolves all XsdReferences in the schema by their corresponding XsdElement or XsdModelGroup terms.
+ */
+ void resolveTermReferences();
+
+ /**
+ * Resolves all XsdReferences in the @p particle recursive by their corresponding XsdElement or XsdModelGroup terms.
+ */
+ void resolveTermReference(const XsdParticle::Ptr &particle, QSet<QXmlName> visitedGroups);
+
+ /**
+ * Resolves all XsdAttributeReferences in the schema by their corresponding XsdAttributeUse objects.
+ */
+ void resolveAttributeTermReferences();
+
+ /**
+ * Resolves all XsdAttributeReferences in the list of @p attributeUses by their corresponding XsdAttributeUse objects.
+ */
+ XsdAttributeUse::List resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet<QXmlName> visitedAttributeGroups);
+
+ /**
+ * Resolves the attribute inheritance of complex types.
+ *
+ * @note This method must be called after all base types have been resolved.
+ */
+ void resolveAttributeInheritance();
+
+ /**
+ * Resolves the attribute inheritance of the given complex types.
+ *
+ * @param complexType The complex type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ *
+ * @note This method must be called after all base types have been resolved.
+ */
+ void resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves the enumeration facet values for QName and NOTATION based facets.
+ */
+ void resolveEnumerationFacetValues();
+
+ /**
+ * Returns the source location of the given schema @p component or a dummy
+ * source location if the component is not found in the component location hash.
+ */
+ QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr component) const;
+
+ /**
+ * Returns the facets that are marked for the given complex @p type with a simple
+ * type restriction.
+ */
+ XsdFacet::Hash complexTypeFacets(const XsdComplexType::Ptr &complexType) const;
+
+ /**
+ * Finds the primitive type for the given simple @p type.
+ *
+ * The type is found by walking up the inheritance tree, until one of the builtin
+ * primitive type definitions is reached.
+ */
+ AnySimpleType::Ptr findPrimitiveType(const AnySimpleType::Ptr &type, QSet<AnySimpleType::Ptr> &visitedTypes);
+
+ /**
+ * Checks the redefined groups.
+ */
+ void checkRedefinedGroups();
+
+ /**
+ * Checks the redefined attribute groups.
+ */
+ void checkRedefinedAttributeGroups();
+
+ class KeyReference
+ {
+ public:
+ XsdElement::Ptr element;
+ XsdIdentityConstraint::Ptr keyRef;
+ QXmlName reference;
+ QSourceLocation location;
+ };
+
+ class SimpleRestrictionBase
+ {
+ public:
+ XsdSimpleType::Ptr simpleType;
+ QXmlName baseName;
+ QSourceLocation location;
+ };
+
+ class SimpleListType
+ {
+ public:
+ XsdSimpleType::Ptr simpleType;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class SimpleUnionType
+ {
+ public:
+ XsdSimpleType::Ptr simpleType;
+ QList<QXmlName> typeNames;
+ QSourceLocation location;
+ };
+
+ class ElementType
+ {
+ public:
+ XsdElement::Ptr element;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class ComplexBaseType
+ {
+ public:
+ XsdComplexType::Ptr complexType;
+ QXmlName baseName;
+ QSourceLocation location;
+ XsdFacet::Hash facets;
+ };
+
+ class ComplexContentType
+ {
+ public:
+ XsdComplexType::Ptr complexType;
+ XsdParticle::Ptr explicitContent;
+ bool effectiveMixed;
+ };
+
+ class AttributeType
+ {
+ public:
+ XsdAttribute::Ptr attribute;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class AlternativeType
+ {
+ public:
+ XsdAlternative::Ptr alternative;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class AlternativeTypeElement
+ {
+ public:
+ XsdAlternative::Ptr alternative;
+ XsdElement::Ptr element;
+ };
+
+ class SubstitutionGroupAffiliation
+ {
+ public:
+ XsdElement::Ptr element;
+ QList<QXmlName> elementNames;
+ QSourceLocation location;
+ };
+
+ class RedefinedGroups
+ {
+ public:
+ XsdModelGroup::Ptr redefinedGroup;
+ XsdModelGroup::Ptr group;
+ };
+
+ class RedefinedAttributeGroups
+ {
+ public:
+ XsdAttributeGroup::Ptr redefinedGroup;
+ XsdAttributeGroup::Ptr group;
+ };
+
+ QVector<KeyReference> m_keyReferences;
+ QVector<SimpleRestrictionBase> m_simpleRestrictionBases;
+ QVector<SimpleListType> m_simpleListTypes;
+ QVector<SimpleUnionType> m_simpleUnionTypes;
+ QVector<ElementType> m_elementTypes;
+ QVector<ComplexBaseType> m_complexBaseTypes;
+ QVector<ComplexContentType> m_complexContentTypes;
+ QVector<AttributeType> m_attributeTypes;
+ QVector<AlternativeType> m_alternativeTypes;
+ QVector<AlternativeTypeElement> m_alternativeTypeElements;
+ QVector<SubstitutionGroupAffiliation> m_substitutionGroupAffiliations;
+ QVector<XsdElement::Ptr> m_substitutionGroupTypes;
+ QVector<RedefinedGroups> m_redefinedGroups;
+ QVector<RedefinedAttributeGroups> m_redefinedAttributeGroups;
+ QHash<AtomicValue::Ptr, NamespaceSupport> m_enumerationFacetValues;
+ QSet<XsdReference::Ptr> m_allGroups;
+
+ QExplicitlySharedDataPointer<XsdSchemaContext> m_context;
+ QExplicitlySharedDataPointer<XsdSchemaChecker> m_checker;
+ NamePool::Ptr m_namePool;
+ XsdSchema::Ptr m_schema;
+ QHash<NamedSchemaComponent::Ptr, QSourceLocation> m_componentLocationHash;
+ XsdComplexType::OpenContent::Ptr m_defaultOpenContent;
+ bool m_defaultOpenContentAppliesToEmpty;
+ SchemaType::List m_predefinedSchemaTypes;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschematoken.cpp b/src/xmlpatterns/schema/qxsdschematoken.cpp
new file mode 100644
index 0000000..a04f8ae
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematoken.cpp
@@ -0,0 +1,2981 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */
+
+#include "qxsdschematoken_p.h"
+
+QT_BEGIN_NAMESPACE
+
+XsdSchemaToken::NodeName XsdSchemaToken::classifier2(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 100
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Id;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier3(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+ if (data[1] == 108)
+
+
+ {
+
+ if(data[2] == 108)
+
+
+ return All;
+
+ }
+
+ else if (data[1] == 110)
+
+
+ {
+
+ if(data[2] == 121)
+
+
+ return Any;
+
+ }
+
+
+ }
+
+ else if (data[0] == 107)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Key;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Ref;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Use;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier4(const QChar *data)
+
+ {
+ if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Base;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Form;
+
+ }
+
+ else if (data[0] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 115, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return List;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Mode;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Name;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Test;
+
+ }
+
+ else if (data[1] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Type;
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier5(const QChar *data)
+
+ {
+ if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 111, 99, 107
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Block;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+ if (data[1] == 105)
+
+
+ {
+ if (data[2] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 100
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Field;
+
+ }
+
+ else if (data[2] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Final;
+
+ }
+
+ else if (data[2] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 100
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Fixed;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 103)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 111, 117, 112
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Group;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 120, 101, 100
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Mixed;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 101, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Refer;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Union;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108, 117, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Value;
+
+ }
+
+ else if (data[0] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 97, 116, 104
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Xpath;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier6(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 115, 101, 114, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Assert;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 111, 105, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Choice;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 112, 111, 114, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Import;
+
+ }
+
+ else if (data[0] == 107)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 121, 114, 101, 102
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Keyref;
+
+ }
+
+ else if (data[0] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 110, 103, 116, 104
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Length;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 98, 108, 105, 99
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Public;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 101, 109, 97
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Schema;
+
+ }
+
+ else if (data[1] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 114, 99, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Source;
+
+ }
+
+ else if (data[1] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 116, 101, 109
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return System;
+
+ }
+
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 105, 113, 117, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Unique;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier7(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 112, 105, 110, 102, 111
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Appinfo;
+
+ }
+
+ else if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Default;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Element;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Include;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 116, 101, 114, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Pattern;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 112, 108, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Replace;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 114, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Version;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier8(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 98, 115, 116, 114, 97, 99, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Abstract;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 108, 108, 97, 112, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Collapse;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 101, 109, 84, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return ItemType;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+ if (data[1] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 108, 97, 98, 108, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Nillable;
+
+ }
+
+ else if (data[1] == 111)
+
+
+ {
+ if (data[2] == 116)
+
+
+ {
+ if (data[3] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 105, 111, 110
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Notation;
+
+ }
+
+ else if (data[3] == 81)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 78, 97, 109, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 4) == 0)
+
+
+ return NotQName;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 118, 101, 114, 114, 105, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Override;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 101, 115, 101, 114, 118, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Preserve;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 100, 101, 102, 105, 110, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Redefine;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+ if (data[2] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 99, 116, 111, 114
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Selector;
+
+ }
+
+ else if (data[2] == 113)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 101, 110, 99, 101
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Sequence;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 108, 58, 108, 97, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return XmlLanguage;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier9(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+ if (data[1] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101, 114, 116, 105, 111, 110
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Assertion;
+
+ }
+
+ else if (data[1] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 114, 105, 98, 117, 116, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Attribute;
+
+ }
+
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 116, 101, 110, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Extension;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+ if (data[1] == 97)
+
+
+ {
+ if (data[2] == 120)
+
+
+ {
+ if (data[3] == 76)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 110, 103, 116, 104
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MaxLength;
+
+ }
+
+ else if (data[3] == 79)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 99, 117, 114, 115
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MaxOccurs;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[1] == 105)
+
+
+ {
+ if (data[2] == 110)
+
+
+ {
+ if (data[3] == 76)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 110, 103, 116, 104
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MinLength;
+
+ }
+
+ else if (data[3] == 79)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 99, 117, 114, 115
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MinOccurs;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Namespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier10(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 110, 111, 116, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return Annotation;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 109, 112, 108, 101, 84, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return SimpleType;
+
+ }
+
+ else if (data[0] == 119)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 105, 116, 101, 83, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return WhiteSpace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier11(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 116, 101, 114, 110, 97, 116, 105, 118, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return Alternative;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 109, 112, 108, 101, 120, 84, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return ComplexType;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 117, 109, 101, 114, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return Enumeration;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 109, 98, 101, 114, 84, 121, 112, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return MemberTypes;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101, 110, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return OpenContent;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 116, 114, 105, 99, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return Restriction;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 116, 97, 108, 68, 105, 103, 105, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return TotalDigits;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier12(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 121, 65, 116, 116, 114, 105, 98, 117, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return AnyAttribute;
+
+ }
+
+ else if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 111, 99, 107, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return BlockDefault;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 110, 97, 108, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return FinalDefault;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+ if (data[1] == 97)
+
+
+ {
+ if (data[2] == 120)
+
+
+ {
+ if (data[3] == 69)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MaxExclusive;
+
+ }
+
+ else if (data[3] == 73)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MaxInclusive;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[1] == 105)
+
+
+ {
+ if (data[2] == 110)
+
+
+ {
+ if (data[3] == 69)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MinExclusive;
+
+ }
+
+ else if (data[3] == 73)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MinInclusive;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return NotNamespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier13(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return Documentation;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 109, 112, 108, 101, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return SimpleContent;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier14(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+ if (data[1] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 108, 105, 101, 115, 84, 111, 69, 109, 112, 116, 121
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 12) == 0)
+
+
+ return AppliesToEmpty;
+
+ }
+
+ else if (data[1] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 114, 105, 98, 117, 116, 101, 71, 114, 111, 117, 112
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 12) == 0)
+
+
+ return AttributeGroup;
+
+ }
+
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 109, 112, 108, 101, 120, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return ComplexContent;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 97, 99, 116, 105, 111, 110, 68, 105, 103, 105, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return FractionDigits;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 104, 101, 109, 97, 76, 111, 99, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return SchemaLocation;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier15(const QChar *data)
+
+ {
+ if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 111, 99, 101, 115, 115, 67, 111, 110, 116, 101, 110, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ProcessContents;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 114, 103, 101, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return TargetNamespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier17(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 16) == 0)
+
+
+ return DefaultAttributes;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 71, 114, 111, 117, 112
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 16) == 0)
+
+
+ return SubstitutionGroup;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier18(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116, 79, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return DefaultOpenContent;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 109, 101, 110, 116, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return ElementFormDefault;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier20(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 20) == 0)
+
+
+ return AttributeFormDefault;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier21(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 112, 97, 116, 104, 68, 101, 102, 97, 117, 108, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 21) == 0)
+
+
+ return XPathDefaultNamespace;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier22(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 65, 112, 112, 108, 121
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 22) == 0)
+
+
+ return DefaultAttributesApply;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier32(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 32) == 0)
+
+
+ return XML_NS_SCHEMA_URI;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QChar *data, int length)
+ {
+ switch(length)
+ {
+
+ case 2:
+ return classifier2(data);
+
+
+ case 3:
+ return classifier3(data);
+
+
+ case 4:
+ return classifier4(data);
+
+
+ case 5:
+ return classifier5(data);
+
+
+ case 6:
+ return classifier6(data);
+
+
+ case 7:
+ return classifier7(data);
+
+
+ case 8:
+ return classifier8(data);
+
+
+ case 9:
+ return classifier9(data);
+
+
+ case 10:
+ return classifier10(data);
+
+
+ case 11:
+ return classifier11(data);
+
+
+ case 12:
+ return classifier12(data);
+
+
+ case 13:
+ return classifier13(data);
+
+
+ case 14:
+ return classifier14(data);
+
+
+ case 15:
+ return classifier15(data);
+
+
+ case 17:
+ return classifier17(data);
+
+
+ case 18:
+ return classifier18(data);
+
+
+ case 20:
+ return classifier20(data);
+
+
+ case 21:
+ return classifier21(data);
+
+
+ case 22:
+ return classifier22(data);
+
+
+ case 32:
+ return classifier32(data);
+
+
+ default:
+ return NoKeyword;
+ }
+ }
+
+
+ QString XsdSchemaToken::toString(NodeName token)
+ {
+ const unsigned short *data = 0;
+ int length = 0;
+
+ switch(token)
+ {
+
+ case Abstract:
+ {
+ static const unsigned short staticallyStoredAbstract[] =
+ {
+ 97, 98, 115, 116, 114, 97, 99, 116, 0
+ };
+ data = staticallyStoredAbstract;
+ length = 8;
+ break;
+ }
+
+ case All:
+ {
+ static const unsigned short staticallyStoredAll[] =
+ {
+ 97, 108, 108, 0
+ };
+ data = staticallyStoredAll;
+ length = 3;
+ break;
+ }
+
+ case Alternative:
+ {
+ static const unsigned short staticallyStoredAlternative[] =
+ {
+ 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 0
+ };
+ data = staticallyStoredAlternative;
+ length = 11;
+ break;
+ }
+
+ case Annotation:
+ {
+ static const unsigned short staticallyStoredAnnotation[] =
+ {
+ 97, 110, 110, 111, 116, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredAnnotation;
+ length = 10;
+ break;
+ }
+
+ case Any:
+ {
+ static const unsigned short staticallyStoredAny[] =
+ {
+ 97, 110, 121, 0
+ };
+ data = staticallyStoredAny;
+ length = 3;
+ break;
+ }
+
+ case AnyAttribute:
+ {
+ static const unsigned short staticallyStoredAnyAttribute[] =
+ {
+ 97, 110, 121, 65, 116, 116, 114, 105, 98, 117, 116, 101, 0
+ };
+ data = staticallyStoredAnyAttribute;
+ length = 12;
+ break;
+ }
+
+ case Appinfo:
+ {
+ static const unsigned short staticallyStoredAppinfo[] =
+ {
+ 97, 112, 112, 105, 110, 102, 111, 0
+ };
+ data = staticallyStoredAppinfo;
+ length = 7;
+ break;
+ }
+
+ case AppliesToEmpty:
+ {
+ static const unsigned short staticallyStoredAppliesToEmpty[] =
+ {
+ 97, 112, 112, 108, 105, 101, 115, 84, 111, 69, 109, 112, 116, 121, 0
+ };
+ data = staticallyStoredAppliesToEmpty;
+ length = 14;
+ break;
+ }
+
+ case Assert:
+ {
+ static const unsigned short staticallyStoredAssert[] =
+ {
+ 97, 115, 115, 101, 114, 116, 0
+ };
+ data = staticallyStoredAssert;
+ length = 6;
+ break;
+ }
+
+ case Assertion:
+ {
+ static const unsigned short staticallyStoredAssertion[] =
+ {
+ 97, 115, 115, 101, 114, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredAssertion;
+ length = 9;
+ break;
+ }
+
+ case Attribute:
+ {
+ static const unsigned short staticallyStoredAttribute[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 0
+ };
+ data = staticallyStoredAttribute;
+ length = 9;
+ break;
+ }
+
+ case AttributeFormDefault:
+ {
+ static const unsigned short staticallyStoredAttributeFormDefault[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredAttributeFormDefault;
+ length = 20;
+ break;
+ }
+
+ case AttributeGroup:
+ {
+ static const unsigned short staticallyStoredAttributeGroup[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 71, 114, 111, 117, 112, 0
+ };
+ data = staticallyStoredAttributeGroup;
+ length = 14;
+ break;
+ }
+
+ case Base:
+ {
+ static const unsigned short staticallyStoredBase[] =
+ {
+ 98, 97, 115, 101, 0
+ };
+ data = staticallyStoredBase;
+ length = 4;
+ break;
+ }
+
+ case Block:
+ {
+ static const unsigned short staticallyStoredBlock[] =
+ {
+ 98, 108, 111, 99, 107, 0
+ };
+ data = staticallyStoredBlock;
+ length = 5;
+ break;
+ }
+
+ case BlockDefault:
+ {
+ static const unsigned short staticallyStoredBlockDefault[] =
+ {
+ 98, 108, 111, 99, 107, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredBlockDefault;
+ length = 12;
+ break;
+ }
+
+ case Choice:
+ {
+ static const unsigned short staticallyStoredChoice[] =
+ {
+ 99, 104, 111, 105, 99, 101, 0
+ };
+ data = staticallyStoredChoice;
+ length = 6;
+ break;
+ }
+
+ case Collapse:
+ {
+ static const unsigned short staticallyStoredCollapse[] =
+ {
+ 99, 111, 108, 108, 97, 112, 115, 101, 0
+ };
+ data = staticallyStoredCollapse;
+ length = 8;
+ break;
+ }
+
+ case ComplexContent:
+ {
+ static const unsigned short staticallyStoredComplexContent[] =
+ {
+ 99, 111, 109, 112, 108, 101, 120, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredComplexContent;
+ length = 14;
+ break;
+ }
+
+ case ComplexType:
+ {
+ static const unsigned short staticallyStoredComplexType[] =
+ {
+ 99, 111, 109, 112, 108, 101, 120, 84, 121, 112, 101, 0
+ };
+ data = staticallyStoredComplexType;
+ length = 11;
+ break;
+ }
+
+ case Default:
+ {
+ static const unsigned short staticallyStoredDefault[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredDefault;
+ length = 7;
+ break;
+ }
+
+ case DefaultAttributes:
+ {
+ static const unsigned short staticallyStoredDefaultAttributes[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 0
+ };
+ data = staticallyStoredDefaultAttributes;
+ length = 17;
+ break;
+ }
+
+ case DefaultAttributesApply:
+ {
+ static const unsigned short staticallyStoredDefaultAttributesApply[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 65, 112, 112, 108, 121, 0
+ };
+ data = staticallyStoredDefaultAttributesApply;
+ length = 22;
+ break;
+ }
+
+ case DefaultOpenContent:
+ {
+ static const unsigned short staticallyStoredDefaultOpenContent[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 79, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredDefaultOpenContent;
+ length = 18;
+ break;
+ }
+
+ case Documentation:
+ {
+ static const unsigned short staticallyStoredDocumentation[] =
+ {
+ 100, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredDocumentation;
+ length = 13;
+ break;
+ }
+
+ case Element:
+ {
+ static const unsigned short staticallyStoredElement[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredElement;
+ length = 7;
+ break;
+ }
+
+ case ElementFormDefault:
+ {
+ static const unsigned short staticallyStoredElementFormDefault[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredElementFormDefault;
+ length = 18;
+ break;
+ }
+
+ case Enumeration:
+ {
+ static const unsigned short staticallyStoredEnumeration[] =
+ {
+ 101, 110, 117, 109, 101, 114, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredEnumeration;
+ length = 11;
+ break;
+ }
+
+ case Extension:
+ {
+ static const unsigned short staticallyStoredExtension[] =
+ {
+ 101, 120, 116, 101, 110, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredExtension;
+ length = 9;
+ break;
+ }
+
+ case Field:
+ {
+ static const unsigned short staticallyStoredField[] =
+ {
+ 102, 105, 101, 108, 100, 0
+ };
+ data = staticallyStoredField;
+ length = 5;
+ break;
+ }
+
+ case Final:
+ {
+ static const unsigned short staticallyStoredFinal[] =
+ {
+ 102, 105, 110, 97, 108, 0
+ };
+ data = staticallyStoredFinal;
+ length = 5;
+ break;
+ }
+
+ case FinalDefault:
+ {
+ static const unsigned short staticallyStoredFinalDefault[] =
+ {
+ 102, 105, 110, 97, 108, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredFinalDefault;
+ length = 12;
+ break;
+ }
+
+ case Fixed:
+ {
+ static const unsigned short staticallyStoredFixed[] =
+ {
+ 102, 105, 120, 101, 100, 0
+ };
+ data = staticallyStoredFixed;
+ length = 5;
+ break;
+ }
+
+ case Form:
+ {
+ static const unsigned short staticallyStoredForm[] =
+ {
+ 102, 111, 114, 109, 0
+ };
+ data = staticallyStoredForm;
+ length = 4;
+ break;
+ }
+
+ case FractionDigits:
+ {
+ static const unsigned short staticallyStoredFractionDigits[] =
+ {
+ 102, 114, 97, 99, 116, 105, 111, 110, 68, 105, 103, 105, 116, 115, 0
+ };
+ data = staticallyStoredFractionDigits;
+ length = 14;
+ break;
+ }
+
+ case Group:
+ {
+ static const unsigned short staticallyStoredGroup[] =
+ {
+ 103, 114, 111, 117, 112, 0
+ };
+ data = staticallyStoredGroup;
+ length = 5;
+ break;
+ }
+
+ case Id:
+ {
+ static const unsigned short staticallyStoredId[] =
+ {
+ 105, 100, 0
+ };
+ data = staticallyStoredId;
+ length = 2;
+ break;
+ }
+
+ case Import:
+ {
+ static const unsigned short staticallyStoredImport[] =
+ {
+ 105, 109, 112, 111, 114, 116, 0
+ };
+ data = staticallyStoredImport;
+ length = 6;
+ break;
+ }
+
+ case Include:
+ {
+ static const unsigned short staticallyStoredInclude[] =
+ {
+ 105, 110, 99, 108, 117, 100, 101, 0
+ };
+ data = staticallyStoredInclude;
+ length = 7;
+ break;
+ }
+
+ case ItemType:
+ {
+ static const unsigned short staticallyStoredItemType[] =
+ {
+ 105, 116, 101, 109, 84, 121, 112, 101, 0
+ };
+ data = staticallyStoredItemType;
+ length = 8;
+ break;
+ }
+
+ case Key:
+ {
+ static const unsigned short staticallyStoredKey[] =
+ {
+ 107, 101, 121, 0
+ };
+ data = staticallyStoredKey;
+ length = 3;
+ break;
+ }
+
+ case Keyref:
+ {
+ static const unsigned short staticallyStoredKeyref[] =
+ {
+ 107, 101, 121, 114, 101, 102, 0
+ };
+ data = staticallyStoredKeyref;
+ length = 6;
+ break;
+ }
+
+ case Length:
+ {
+ static const unsigned short staticallyStoredLength[] =
+ {
+ 108, 101, 110, 103, 116, 104, 0
+ };
+ data = staticallyStoredLength;
+ length = 6;
+ break;
+ }
+
+ case List:
+ {
+ static const unsigned short staticallyStoredList[] =
+ {
+ 108, 105, 115, 116, 0
+ };
+ data = staticallyStoredList;
+ length = 4;
+ break;
+ }
+
+ case MaxExclusive:
+ {
+ static const unsigned short staticallyStoredMaxExclusive[] =
+ {
+ 109, 97, 120, 69, 120, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMaxExclusive;
+ length = 12;
+ break;
+ }
+
+ case MaxInclusive:
+ {
+ static const unsigned short staticallyStoredMaxInclusive[] =
+ {
+ 109, 97, 120, 73, 110, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMaxInclusive;
+ length = 12;
+ break;
+ }
+
+ case MaxLength:
+ {
+ static const unsigned short staticallyStoredMaxLength[] =
+ {
+ 109, 97, 120, 76, 101, 110, 103, 116, 104, 0
+ };
+ data = staticallyStoredMaxLength;
+ length = 9;
+ break;
+ }
+
+ case MaxOccurs:
+ {
+ static const unsigned short staticallyStoredMaxOccurs[] =
+ {
+ 109, 97, 120, 79, 99, 99, 117, 114, 115, 0
+ };
+ data = staticallyStoredMaxOccurs;
+ length = 9;
+ break;
+ }
+
+ case MemberTypes:
+ {
+ static const unsigned short staticallyStoredMemberTypes[] =
+ {
+ 109, 101, 109, 98, 101, 114, 84, 121, 112, 101, 115, 0
+ };
+ data = staticallyStoredMemberTypes;
+ length = 11;
+ break;
+ }
+
+ case MinExclusive:
+ {
+ static const unsigned short staticallyStoredMinExclusive[] =
+ {
+ 109, 105, 110, 69, 120, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMinExclusive;
+ length = 12;
+ break;
+ }
+
+ case MinInclusive:
+ {
+ static const unsigned short staticallyStoredMinInclusive[] =
+ {
+ 109, 105, 110, 73, 110, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMinInclusive;
+ length = 12;
+ break;
+ }
+
+ case MinLength:
+ {
+ static const unsigned short staticallyStoredMinLength[] =
+ {
+ 109, 105, 110, 76, 101, 110, 103, 116, 104, 0
+ };
+ data = staticallyStoredMinLength;
+ length = 9;
+ break;
+ }
+
+ case MinOccurs:
+ {
+ static const unsigned short staticallyStoredMinOccurs[] =
+ {
+ 109, 105, 110, 79, 99, 99, 117, 114, 115, 0
+ };
+ data = staticallyStoredMinOccurs;
+ length = 9;
+ break;
+ }
+
+ case Mixed:
+ {
+ static const unsigned short staticallyStoredMixed[] =
+ {
+ 109, 105, 120, 101, 100, 0
+ };
+ data = staticallyStoredMixed;
+ length = 5;
+ break;
+ }
+
+ case Mode:
+ {
+ static const unsigned short staticallyStoredMode[] =
+ {
+ 109, 111, 100, 101, 0
+ };
+ data = staticallyStoredMode;
+ length = 4;
+ break;
+ }
+
+ case Name:
+ {
+ static const unsigned short staticallyStoredName[] =
+ {
+ 110, 97, 109, 101, 0
+ };
+ data = staticallyStoredName;
+ length = 4;
+ break;
+ }
+
+ case Namespace:
+ {
+ static const unsigned short staticallyStoredNamespace[] =
+ {
+ 110, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredNamespace;
+ length = 9;
+ break;
+ }
+
+ case Nillable:
+ {
+ static const unsigned short staticallyStoredNillable[] =
+ {
+ 110, 105, 108, 108, 97, 98, 108, 101, 0
+ };
+ data = staticallyStoredNillable;
+ length = 8;
+ break;
+ }
+
+ case NotNamespace:
+ {
+ static const unsigned short staticallyStoredNotNamespace[] =
+ {
+ 110, 111, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredNotNamespace;
+ length = 12;
+ break;
+ }
+
+ case NotQName:
+ {
+ static const unsigned short staticallyStoredNotQName[] =
+ {
+ 110, 111, 116, 81, 78, 97, 109, 101, 0
+ };
+ data = staticallyStoredNotQName;
+ length = 8;
+ break;
+ }
+
+ case Notation:
+ {
+ static const unsigned short staticallyStoredNotation[] =
+ {
+ 110, 111, 116, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredNotation;
+ length = 8;
+ break;
+ }
+
+ case OpenContent:
+ {
+ static const unsigned short staticallyStoredOpenContent[] =
+ {
+ 111, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredOpenContent;
+ length = 11;
+ break;
+ }
+
+ case Override:
+ {
+ static const unsigned short staticallyStoredOverride[] =
+ {
+ 111, 118, 101, 114, 114, 105, 100, 101, 0
+ };
+ data = staticallyStoredOverride;
+ length = 8;
+ break;
+ }
+
+ case Pattern:
+ {
+ static const unsigned short staticallyStoredPattern[] =
+ {
+ 112, 97, 116, 116, 101, 114, 110, 0
+ };
+ data = staticallyStoredPattern;
+ length = 7;
+ break;
+ }
+
+ case Preserve:
+ {
+ static const unsigned short staticallyStoredPreserve[] =
+ {
+ 112, 114, 101, 115, 101, 114, 118, 101, 0
+ };
+ data = staticallyStoredPreserve;
+ length = 8;
+ break;
+ }
+
+ case ProcessContents:
+ {
+ static const unsigned short staticallyStoredProcessContents[] =
+ {
+ 112, 114, 111, 99, 101, 115, 115, 67, 111, 110, 116, 101, 110, 116, 115, 0
+ };
+ data = staticallyStoredProcessContents;
+ length = 15;
+ break;
+ }
+
+ case Public:
+ {
+ static const unsigned short staticallyStoredPublic[] =
+ {
+ 112, 117, 98, 108, 105, 99, 0
+ };
+ data = staticallyStoredPublic;
+ length = 6;
+ break;
+ }
+
+ case Redefine:
+ {
+ static const unsigned short staticallyStoredRedefine[] =
+ {
+ 114, 101, 100, 101, 102, 105, 110, 101, 0
+ };
+ data = staticallyStoredRedefine;
+ length = 8;
+ break;
+ }
+
+ case Ref:
+ {
+ static const unsigned short staticallyStoredRef[] =
+ {
+ 114, 101, 102, 0
+ };
+ data = staticallyStoredRef;
+ length = 3;
+ break;
+ }
+
+ case Refer:
+ {
+ static const unsigned short staticallyStoredRefer[] =
+ {
+ 114, 101, 102, 101, 114, 0
+ };
+ data = staticallyStoredRefer;
+ length = 5;
+ break;
+ }
+
+ case Replace:
+ {
+ static const unsigned short staticallyStoredReplace[] =
+ {
+ 114, 101, 112, 108, 97, 99, 101, 0
+ };
+ data = staticallyStoredReplace;
+ length = 7;
+ break;
+ }
+
+ case Restriction:
+ {
+ static const unsigned short staticallyStoredRestriction[] =
+ {
+ 114, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredRestriction;
+ length = 11;
+ break;
+ }
+
+ case Schema:
+ {
+ static const unsigned short staticallyStoredSchema[] =
+ {
+ 115, 99, 104, 101, 109, 97, 0
+ };
+ data = staticallyStoredSchema;
+ length = 6;
+ break;
+ }
+
+ case SchemaLocation:
+ {
+ static const unsigned short staticallyStoredSchemaLocation[] =
+ {
+ 115, 99, 104, 101, 109, 97, 76, 111, 99, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredSchemaLocation;
+ length = 14;
+ break;
+ }
+
+ case Selector:
+ {
+ static const unsigned short staticallyStoredSelector[] =
+ {
+ 115, 101, 108, 101, 99, 116, 111, 114, 0
+ };
+ data = staticallyStoredSelector;
+ length = 8;
+ break;
+ }
+
+ case Sequence:
+ {
+ static const unsigned short staticallyStoredSequence[] =
+ {
+ 115, 101, 113, 117, 101, 110, 99, 101, 0
+ };
+ data = staticallyStoredSequence;
+ length = 8;
+ break;
+ }
+
+ case SimpleContent:
+ {
+ static const unsigned short staticallyStoredSimpleContent[] =
+ {
+ 115, 105, 109, 112, 108, 101, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredSimpleContent;
+ length = 13;
+ break;
+ }
+
+ case SimpleType:
+ {
+ static const unsigned short staticallyStoredSimpleType[] =
+ {
+ 115, 105, 109, 112, 108, 101, 84, 121, 112, 101, 0
+ };
+ data = staticallyStoredSimpleType;
+ length = 10;
+ break;
+ }
+
+ case Source:
+ {
+ static const unsigned short staticallyStoredSource[] =
+ {
+ 115, 111, 117, 114, 99, 101, 0
+ };
+ data = staticallyStoredSource;
+ length = 6;
+ break;
+ }
+
+ case SubstitutionGroup:
+ {
+ static const unsigned short staticallyStoredSubstitutionGroup[] =
+ {
+ 115, 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 71, 114, 111, 117, 112, 0
+ };
+ data = staticallyStoredSubstitutionGroup;
+ length = 17;
+ break;
+ }
+
+ case System:
+ {
+ static const unsigned short staticallyStoredSystem[] =
+ {
+ 115, 121, 115, 116, 101, 109, 0
+ };
+ data = staticallyStoredSystem;
+ length = 6;
+ break;
+ }
+
+ case TargetNamespace:
+ {
+ static const unsigned short staticallyStoredTargetNamespace[] =
+ {
+ 116, 97, 114, 103, 101, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredTargetNamespace;
+ length = 15;
+ break;
+ }
+
+ case Test:
+ {
+ static const unsigned short staticallyStoredTest[] =
+ {
+ 116, 101, 115, 116, 0
+ };
+ data = staticallyStoredTest;
+ length = 4;
+ break;
+ }
+
+ case TotalDigits:
+ {
+ static const unsigned short staticallyStoredTotalDigits[] =
+ {
+ 116, 111, 116, 97, 108, 68, 105, 103, 105, 116, 115, 0
+ };
+ data = staticallyStoredTotalDigits;
+ length = 11;
+ break;
+ }
+
+ case Type:
+ {
+ static const unsigned short staticallyStoredType[] =
+ {
+ 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredType;
+ length = 4;
+ break;
+ }
+
+ case Union:
+ {
+ static const unsigned short staticallyStoredUnion[] =
+ {
+ 117, 110, 105, 111, 110, 0
+ };
+ data = staticallyStoredUnion;
+ length = 5;
+ break;
+ }
+
+ case Unique:
+ {
+ static const unsigned short staticallyStoredUnique[] =
+ {
+ 117, 110, 105, 113, 117, 101, 0
+ };
+ data = staticallyStoredUnique;
+ length = 6;
+ break;
+ }
+
+ case Use:
+ {
+ static const unsigned short staticallyStoredUse[] =
+ {
+ 117, 115, 101, 0
+ };
+ data = staticallyStoredUse;
+ length = 3;
+ break;
+ }
+
+ case Value:
+ {
+ static const unsigned short staticallyStoredValue[] =
+ {
+ 118, 97, 108, 117, 101, 0
+ };
+ data = staticallyStoredValue;
+ length = 5;
+ break;
+ }
+
+ case Version:
+ {
+ static const unsigned short staticallyStoredVersion[] =
+ {
+ 118, 101, 114, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredVersion;
+ length = 7;
+ break;
+ }
+
+ case WhiteSpace:
+ {
+ static const unsigned short staticallyStoredWhiteSpace[] =
+ {
+ 119, 104, 105, 116, 101, 83, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredWhiteSpace;
+ length = 10;
+ break;
+ }
+
+ case XML_NS_SCHEMA_URI:
+ {
+ static const unsigned short staticallyStoredXML_NS_SCHEMA_URI[] =
+ {
+ 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 0
+ };
+ data = staticallyStoredXML_NS_SCHEMA_URI;
+ length = 32;
+ break;
+ }
+
+ case XPathDefaultNamespace:
+ {
+ static const unsigned short staticallyStoredXPathDefaultNamespace[] =
+ {
+ 120, 112, 97, 116, 104, 68, 101, 102, 97, 117, 108, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredXPathDefaultNamespace;
+ length = 21;
+ break;
+ }
+
+ case XmlLanguage:
+ {
+ static const unsigned short staticallyStoredXmlLanguage[] =
+ {
+ 120, 109, 108, 58, 108, 97, 110, 103, 0
+ };
+ data = staticallyStoredXmlLanguage;
+ length = 8;
+ break;
+ }
+
+ case Xpath:
+ {
+ static const unsigned short staticallyStoredXpath[] =
+ {
+ 120, 112, 97, 116, 104, 0
+ };
+ data = staticallyStoredXpath;
+ length = 5;
+ break;
+ }
+
+ default:
+ /* It's either the default token, or an undefined enum
+ * value. We silence a compiler warning, and return the
+ * empty string. */
+ ;
+ }
+
+ union
+ {
+ const unsigned short *data;
+ const QChar *asQChar;
+ } converter;
+ converter.data = data;
+
+ return QString::fromRawData(converter.asQChar, length);
+ }
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/schema/qxsdschematoken_p.h b/src/xmlpatterns/schema/qxsdschematoken_p.h
new file mode 100644
index 0000000..fbf71f0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematoken_p.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+//
+
+/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */
+
+#ifndef QPatternist_XsdSchemaToken_h
+#define QPatternist_XsdSchemaToken_h
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+class XsdSchemaToken
+ {
+ public:
+ enum NodeName
+
+ {
+ NoKeyword,
+Abstract,
+All,
+Alternative,
+Annotation,
+Any,
+AnyAttribute,
+Appinfo,
+AppliesToEmpty,
+Assert,
+Assertion,
+Attribute,
+AttributeFormDefault,
+AttributeGroup,
+Base,
+Block,
+BlockDefault,
+Choice,
+Collapse,
+ComplexContent,
+ComplexType,
+Default,
+DefaultAttributes,
+DefaultAttributesApply,
+DefaultOpenContent,
+Documentation,
+Element,
+ElementFormDefault,
+Enumeration,
+Extension,
+Field,
+Final,
+FinalDefault,
+Fixed,
+Form,
+FractionDigits,
+Group,
+Id,
+Import,
+Include,
+ItemType,
+Key,
+Keyref,
+Length,
+List,
+MaxExclusive,
+MaxInclusive,
+MaxLength,
+MaxOccurs,
+MemberTypes,
+MinExclusive,
+MinInclusive,
+MinLength,
+MinOccurs,
+Mixed,
+Mode,
+Name,
+Namespace,
+Nillable,
+NotNamespace,
+NotQName,
+Notation,
+OpenContent,
+Override,
+Pattern,
+Preserve,
+ProcessContents,
+Public,
+Redefine,
+Ref,
+Refer,
+Replace,
+Restriction,
+Schema,
+SchemaLocation,
+Selector,
+Sequence,
+SimpleContent,
+SimpleType,
+Source,
+SubstitutionGroup,
+System,
+TargetNamespace,
+Test,
+TotalDigits,
+Type,
+Union,
+Unique,
+Use,
+Value,
+Version,
+WhiteSpace,
+XML_NS_SCHEMA_URI,
+XPathDefaultNamespace,
+XmlLanguage,
+Xpath
+ };
+
+ static inline NodeName toToken(const QString &value);
+static inline NodeName toToken(const QStringRef &value);
+static NodeName toToken(const QChar *data, int length);
+static QString toString(NodeName token);
+
+
+ private:
+ static inline NodeName classifier2(const QChar *data);
+static inline NodeName classifier3(const QChar *data);
+static inline NodeName classifier4(const QChar *data);
+static inline NodeName classifier5(const QChar *data);
+static inline NodeName classifier6(const QChar *data);
+static inline NodeName classifier7(const QChar *data);
+static inline NodeName classifier8(const QChar *data);
+static inline NodeName classifier9(const QChar *data);
+static inline NodeName classifier10(const QChar *data);
+static inline NodeName classifier11(const QChar *data);
+static inline NodeName classifier12(const QChar *data);
+static inline NodeName classifier13(const QChar *data);
+static inline NodeName classifier14(const QChar *data);
+static inline NodeName classifier15(const QChar *data);
+static inline NodeName classifier17(const QChar *data);
+static inline NodeName classifier18(const QChar *data);
+static inline NodeName classifier20(const QChar *data);
+static inline NodeName classifier21(const QChar *data);
+static inline NodeName classifier22(const QChar *data);
+static inline NodeName classifier32(const QChar *data);
+
+ };
+
+ inline XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QString &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+ inline XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QStringRef &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory.cpp b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp
new file mode 100644
index 0000000..b5f319b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschematypesfactory_p.h"
+
+#include "qbasictypesfactory_p.h"
+#include "qbuiltintypes_p.h"
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qxsdschematoken_p.h"
+#include "qxsdsimpletype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaTypesFactory::XsdSchemaTypesFactory(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+ m_types.reserve(3);
+
+ const XsdFacet::Ptr whiteSpaceFacet(new XsdFacet());
+ whiteSpaceFacet->setType(XsdFacet::WhiteSpace);
+ whiteSpaceFacet->setFixed(true);
+ whiteSpaceFacet->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+
+ const XsdFacet::Ptr minLengthFacet(new XsdFacet());
+ minLengthFacet->setType(XsdFacet::MinimumLength);
+ minLengthFacet->setValue(DerivedInteger<TypeNonNegativeInteger>::fromLexical(namePool, QLatin1String("1")));
+
+ XsdFacet::Hash facets;
+ facets.insert(whiteSpaceFacet->type(), whiteSpaceFacet);
+ facets.insert(minLengthFacet->type(), minLengthFacet);
+
+ {
+ const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("NMTOKENS"));
+ const XsdSimpleType::Ptr type(new XsdSimpleType());
+ type->setName(typeName);
+ type->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+ type->setCategory(XsdSimpleType::SimpleTypeList);
+ type->setItemType(BuiltinTypes::xsNMTOKEN);
+ type->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ type->setFacets(facets);
+ m_types.insert(typeName, type);
+ }
+ {
+ const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS"));
+ const XsdSimpleType::Ptr type(new XsdSimpleType());
+ type->setName(typeName);
+ type->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+ type->setCategory(XsdSimpleType::SimpleTypeList);
+ type->setItemType(BuiltinTypes::xsIDREF);
+ type->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ type->setFacets(facets);
+ m_types.insert(typeName, type);
+ }
+ {
+ const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("ENTITIES"));
+ const XsdSimpleType::Ptr type(new XsdSimpleType());
+ type->setName(typeName);
+ type->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+ type->setCategory(XsdSimpleType::SimpleTypeList);
+ type->setItemType(BuiltinTypes::xsENTITY);
+ type->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ type->setFacets(facets);
+ m_types.insert(typeName, type);
+ }
+}
+
+SchemaType::Ptr XsdSchemaTypesFactory::createSchemaType(const QXmlName name) const
+{
+ if (m_types.contains(name)) {
+ return m_types.value(name);
+ } else {
+ if (!m_basicTypesFactory)
+ m_basicTypesFactory = BasicTypesFactory::self(m_namePool);
+
+ return m_basicTypesFactory->createSchemaType(name);
+ }
+}
+
+SchemaType::Hash XsdSchemaTypesFactory::types() const
+{
+ return m_types;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory_p.h b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h
new file mode 100644
index 0000000..74ecc3c
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSchemaTypesFactory_H
+#define Patternist_XsdSchemaTypesFactory_H
+
+#include <QtCore/QHash>
+#include "qschematypefactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Factory for creating schema types for the types defined in XSD.
+ *
+ * @ingroup Patternist_types
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaTypesFactory : public SchemaTypeFactory
+ {
+ public:
+ /**
+ * Creates a new schema type factory.
+ *
+ * @param namePool The name pool all type names belong to.
+ */
+ XsdSchemaTypesFactory(const NamePool::Ptr &namePool);
+
+ /**
+ * Creates a primitive type for @p name. If @p name is not supported,
+ * @c null is returned.
+ *
+ * @note This does not handle user defined types, only builtin types.
+ */
+ virtual SchemaType::Ptr createSchemaType(const QXmlName) const;
+
+ /**
+ * Returns a hash of all available types.
+ */
+ virtual SchemaType::Hash types() const;
+
+ private:
+ /**
+ * A dictonary of all predefined schema types.
+ */
+ SchemaType::Hash m_types;
+
+ NamePool::Ptr m_namePool;
+ mutable SchemaTypeFactory::Ptr m_basicTypesFactory;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdsimpletype.cpp b/src/xmlpatterns/schema/qxsdsimpletype.cpp
new file mode 100644
index 0000000..6fd5658
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdsimpletype.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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.
+
+#include "qxsdsimpletype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QString XsdSimpleType::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(name(np));
+}
+
+void XsdSimpleType::setWxsSuperType(const SchemaType::Ptr &type)
+{
+ m_superType = type;
+}
+
+SchemaType::Ptr XsdSimpleType::wxsSuperType() const
+{
+ return m_superType;
+}
+
+void XsdSimpleType::setContext(const NamedSchemaComponent::Ptr &component)
+{
+ m_context = component;
+}
+
+NamedSchemaComponent::Ptr XsdSimpleType::context() const
+{
+ return m_context;
+}
+
+void XsdSimpleType::setPrimitiveType(const AnySimpleType::Ptr &type)
+{
+ m_primitiveType = type;
+}
+
+AnySimpleType::Ptr XsdSimpleType::primitiveType() const
+{
+ return m_primitiveType;
+}
+
+void XsdSimpleType::setItemType(const AnySimpleType::Ptr &type)
+{
+ m_itemType = type;
+}
+
+AnySimpleType::Ptr XsdSimpleType::itemType() const
+{
+ return m_itemType;
+}
+
+void XsdSimpleType::setMemberTypes(const AnySimpleType::List &types)
+{
+ m_memberTypes = types;
+}
+
+AnySimpleType::List XsdSimpleType::memberTypes() const
+{
+ return m_memberTypes;
+}
+
+void XsdSimpleType::setFacets(const XsdFacet::Hash &facets)
+{
+ m_facets = facets;
+}
+
+XsdFacet::Hash XsdSimpleType::facets() const
+{
+ return m_facets;
+}
+
+void XsdSimpleType::setCategory(TypeCategory category)
+{
+ m_typeCategory = category;
+}
+
+XsdSimpleType::TypeCategory XsdSimpleType::category() const
+{
+ return m_typeCategory;
+}
+
+void XsdSimpleType::setDerivationMethod(DerivationMethod method)
+{
+ m_derivationMethod = method;
+}
+
+XsdSimpleType::DerivationMethod XsdSimpleType::derivationMethod() const
+{
+ return m_derivationMethod;
+}
+
+bool XsdSimpleType::isDefinedBySchema() const
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdsimpletype_p.h b/src/xmlpatterns/schema/qxsdsimpletype_p.h
new file mode 100644
index 0000000..6305fc7
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdsimpletype_p.h
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdSimpleType_H
+#define Patternist_XsdSimpleType_H
+
+#include "qanysimpletype_p.h"
+#include "qxsdfacet_p.h"
+#include "qxsduserschematype_p.h"
+
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD simpleType object.
+ *
+ * This class represents the <em>simpleType</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema-2/#rf-defn">here</a>.
+ *
+ * It contains information from either a top-level simple type declaration (as child of a <em>schema</em> object)
+ * or a local simple type declaration (as descendant of an <em>element</em> or <em>complexType</em> object).
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSSimpleType">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSimpleType : public XsdUserSchemaType<AnySimpleType>
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSimpleType> Ptr;
+
+ /**
+ * Returns the display name of the simple type.
+ *
+ * @param namePool The name pool the type name is stored in.
+ */
+ virtual QString displayName(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Sets the base @p type of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-basetype">Base Type Definition</a>
+ */
+ void setWxsSuperType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the base type of the simple type or an empty pointer if no base type is
+ * set.
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * Sets the context @p component of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#std-context">Context Definition</a>
+ */
+ void setContext(const NamedSchemaComponent::Ptr &component);
+
+ /**
+ * Returns the context component of the simple type.
+ */
+ NamedSchemaComponent::Ptr context() const;
+
+ /**
+ * Sets the primitive @p type of the simple type.
+ *
+ * The primitive type is only specified if the category is SimpleTypeAtomic.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-primitive">Primitive Type Definition</a>
+ */
+ void setPrimitiveType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the primitive type of the simple type or an empty pointer if the category is
+ * not SimpleTypeAtomic.
+ */
+ AnySimpleType::Ptr primitiveType() const;
+
+ /**
+ * Sets the list item @p type of the simple type.
+ *
+ * The list item type is only specified if the category is SimpleTypeList.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-itemType">Item Type Definition</a>
+ */
+ void setItemType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the list item type of the simple type or an empty pointer if the category is
+ * not SimpleTypeList.
+ */
+ AnySimpleType::Ptr itemType() const;
+
+ /**
+ * Sets the member @p types of the simple type.
+ *
+ * The member types are only specified if the category is SimpleTypeUnion.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-memberTypes">Member Types Definition</a>
+ */
+ void setMemberTypes(const AnySimpleType::List &types);
+
+ /**
+ * Returns the list member types of the simple type or an empty list if the category is
+ * not SimpleTypeUnion.
+ */
+ AnySimpleType::List memberTypes() const;
+
+ /**
+ * Sets the @p facets of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-facets">Facets Definition</a>
+ */
+ void setFacets(const XsdFacet::Hash &facets);
+
+ /**
+ * Returns the facets of the simple type.
+ */
+ XsdFacet::Hash facets() const;
+
+ /**
+ * Sets the @p category (variety) of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-variety">Variety Definition</a>
+ */
+ void setCategory(TypeCategory category);
+
+ /**
+ * Returns the category (variety) of the simple type.
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * Sets the derivation @p method of the simple type.
+ *
+ * @see DerivationMethod
+ */
+ void setDerivationMethod(DerivationMethod method);
+
+ /**
+ * Returns the derivation method of the simple type.
+ */
+ virtual DerivationMethod derivationMethod() const;
+
+ /**
+ * Always returns @c true.
+ */
+ virtual bool isDefinedBySchema() const;
+
+ private:
+ SchemaType::Ptr m_superType;
+ NamedSchemaComponent::Ptr m_context;
+ AnySimpleType::Ptr m_primitiveType;
+ AnySimpleType::Ptr m_itemType;
+ AnySimpleType::List m_memberTypes;
+ XsdFacet::Hash m_facets;
+ TypeCategory m_typeCategory;
+ DerivationMethod m_derivationMethod;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp
new file mode 100644
index 0000000..8a43411
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * NOTE: This file is included by qxsdstatemachine_p.h
+ * if you need some includes, put them in qxsdstatemachine_p.h (outside of the namespace)
+ */
+
+template <typename TransitionType>
+XsdStateMachine<TransitionType>::XsdStateMachine()
+ : m_counter(50)
+{
+}
+
+template <typename TransitionType>
+XsdStateMachine<TransitionType>::XsdStateMachine(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+ , m_counter(50)
+{
+}
+
+template <typename TransitionType>
+typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType>::addState(StateType type)
+{
+#ifndef QT_NO_DEBUG
+ // make sure we don't have two start states
+ if (type == StartState) {
+ QHashIterator<StateId, StateType> it(m_states);
+ while (it.hasNext()) {
+ it.next();
+ Q_ASSERT(it.value() != StartState && it.value() != StartEndState);
+ }
+ }
+#endif // QT_NO_DEBUG
+
+ // reserve new state id
+ const StateId id = ++m_counter;
+ m_states.insert(id, type);
+
+ // if it is a start state, we make it to our current state
+ if (type == StartState || type == StartEndState)
+ m_currentState = id;
+
+ return id;
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::addTransition(StateId start, TransitionType transition, StateId end)
+{
+ QHash<TransitionType, QVector<StateId> > &hash = m_transitions[start];
+ QVector<StateId> &states = hash[transition];
+ if (!states.contains(end))
+ states.append(end);
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::addEpsilonTransition(StateId start, StateId end)
+{
+ QVector<StateId> &states = m_epsilonTransitions[start];
+ states.append(end);
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::reset()
+{
+ // reset the machine to the start state
+ QHashIterator<StateId, StateType> it(m_states);
+ while (it.hasNext()) {
+ it.next();
+ if (it.value() == StartState || it.value() == StartEndState) {
+ m_currentState = it.key();
+ return;
+ }
+ }
+
+ Q_ASSERT(false);
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::clear()
+{
+ m_states.clear();
+ m_transitions.clear();
+ m_epsilonTransitions.clear();
+ m_currentState = -1;
+ m_counter = 50;
+}
+
+template <typename TransitionType>
+bool XsdStateMachine<TransitionType>::proceed(TransitionType transition)
+{
+ // check that we are not in an invalid state
+ if (!m_transitions.contains(m_currentState)) {
+ return false;
+ }
+
+ // fetch the transition entry for the current state
+ const QHash<TransitionType, QVector<StateId> > &entry = m_transitions[m_currentState];
+ if (entry.contains(transition)) { // is there an transition for the given input?
+ m_currentState = entry.value(transition).first();
+ m_lastTransition = transition;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+template <typename TransitionType>
+QList<TransitionType> XsdStateMachine<TransitionType>::possibleTransitions() const
+{
+ // check that we are not in an invalid state
+ if (!m_transitions.contains(m_currentState)) {
+ return QList<TransitionType>();
+ }
+
+ // fetch the transition entry for the current state
+ const QHash<TransitionType, QVector<StateId> > &entry = m_transitions[m_currentState];
+
+ return entry.keys();
+}
+
+template <typename TransitionType>
+template <typename InputType>
+bool XsdStateMachine<TransitionType>::proceed(InputType input)
+{
+ // check that we are not in an invalid state
+ if (!m_transitions.contains(m_currentState)) {
+ return false;
+ }
+
+ // fetch the transition entry for the current state
+ const QHash<TransitionType, QVector<StateId> > &entry = m_transitions[m_currentState];
+ QHashIterator<TransitionType, QVector<StateId> > it(entry);
+ while (it.hasNext()) {
+ it.next();
+ if (inputEqualsTransition(input, it.key())) {
+ m_currentState = it.value().first();
+ m_lastTransition = it.key();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <typename TransitionType>
+template <typename InputType>
+bool XsdStateMachine<TransitionType>::inputEqualsTransition(InputType input, TransitionType transition) const
+{
+ return false;
+}
+
+template <typename TransitionType>
+bool XsdStateMachine<TransitionType>::inEndState() const
+{
+ // check if current state is an end state
+ return (m_states.value(m_currentState) == StartEndState || m_states.value(m_currentState) == EndState);
+}
+
+template <typename TransitionType>
+TransitionType XsdStateMachine<TransitionType>::lastTransition() const
+{
+ return m_lastTransition;
+}
+
+template <typename TransitionType>
+typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType>::startState() const
+{
+ QHashIterator<StateId, StateType> it(m_states);
+ while (it.hasNext()) {
+ it.next();
+ if (it.value() == StartState || it.value() == StartEndState)
+ return it.key();
+ }
+
+ Q_ASSERT(false); // should never be reached
+ return -1;
+}
+
+template <typename TransitionType>
+QString XsdStateMachine<TransitionType>::transitionTypeToString(TransitionType type) const
+{
+ Q_UNUSED(type)
+
+ return QString();
+}
+
+template <typename TransitionType>
+bool XsdStateMachine<TransitionType>::outputGraph(QIODevice *device, const QString &graphName) const
+{
+ if (!device->isOpen()) {
+ qWarning("device must be open for writing");
+ return false;
+ }
+
+ QByteArray graph;
+ QTextStream s(&graph);
+
+ QHashIterator<StateId, QHash<TransitionType, QVector<StateId> > > it(m_transitions);
+ QHashIterator<StateId, StateType> it3(m_states);
+
+ s << "digraph " << graphName << " {\n";
+ s << " mindist = 2.0\n";
+
+ // draw edges
+ while (it.hasNext()) {
+ it.next();
+
+ QHashIterator<TransitionType, QVector<StateId> > it2(it.value());
+ while (it2.hasNext()) {
+ it2.next();
+ for (int i = 0; i < it2.value().count(); ++i)
+ s << " " << it.key() << " -> " << it2.value().at(i) << " [label=\"" << transitionTypeToString(it2.key()) << "\"]\n";
+ }
+ }
+
+ QHashIterator<StateId, QVector<StateId> > it4(m_epsilonTransitions);
+ while (it4.hasNext()) {
+ it4.next();
+
+ const QVector<StateId> states = it4.value();
+ for (int i = 0; i < states.count(); ++i)
+ s << " " << it4.key() << " -> " << states.at(i) << " [label=\"&#949;\"]\n";
+ }
+
+ // draw node infos
+ while (it3.hasNext()) {
+ it3.next();
+
+ QString style;
+ if (it3.value() == StartState) {
+ style = QLatin1String("shape=circle, style=filled, color=blue");
+ } else if (it3.value() == StartEndState) {
+ style = QLatin1String("shape=doublecircle, style=filled, color=blue");
+ } else if (it3.value() == InternalState) {
+ style = QLatin1String("shape=circle, style=filled, color=red");
+ } else if (it3.value() == EndState) {
+ style = QLatin1String("shape=doublecircle, style=filled, color=green");
+ }
+
+ s << " " << it3.key() << " [" << style << "]\n";
+ }
+
+ s << "}\n";
+
+ s.flush();
+
+ if (device->write(graph) == -1)
+ return false;
+
+ return true;
+}
+
+
+template <typename TransitionType>
+typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType>::dfaStateForNfaState(QSet<StateId> nfaState,
+ QList< QPair<QSet<StateId>, StateId> > &stateTable,
+ XsdStateMachine<TransitionType> &dfa) const
+{
+ // check whether we have the given state in our lookup table
+ // already, in that case simply return it
+ for (int i = 0; i < stateTable.count(); ++i) {
+ if (stateTable.at(i).first == nfaState)
+ return stateTable.at(i).second;
+ }
+
+ // check if the NFA state set contains a Start or End
+ // state, in that case our new DFA state will be a
+ // Start or End state as well
+ StateType type = InternalState;
+ QSetIterator<StateId> it(nfaState);
+ bool hasStartState = false;
+ bool hasEndState = false;
+ while (it.hasNext()) {
+ const StateId state = it.next();
+ if (m_states.value(state) == EndState) {
+ hasEndState = true;
+ } else if (m_states.value(state) == StartState) {
+ hasStartState = true;
+ }
+ }
+ if (hasStartState) {
+ if (hasEndState)
+ type = StartEndState;
+ else
+ type = StartState;
+ } else if (hasEndState) {
+ type = EndState;
+ }
+
+ // create the new DFA state
+ const StateId dfaState = dfa.addState(type);
+
+ // add the new DFA state to the lookup table
+ stateTable.append(qMakePair<QSet<StateId>, StateId>(nfaState, dfaState));
+
+ return dfaState;
+}
+
+template <typename TransitionType>
+XsdStateMachine<TransitionType> XsdStateMachine<TransitionType>::toDFA() const
+{
+ XsdStateMachine<TransitionType> dfa(m_namePool);
+ dfa.m_counter = 100;
+ QList< QPair< QSet<StateId>, StateId> > table;
+ QList< QSet<StateId> > isMarked;
+
+ // search the start state as the algorithm starts with it...
+ StateId startState = -1;
+ QHashIterator<StateId, StateType> stateTypeIt(m_states);
+ while (stateTypeIt.hasNext()) {
+ stateTypeIt.next();
+ if (stateTypeIt.value() == StartState) {
+ startState = stateTypeIt.key();
+ break;
+ }
+ }
+ Q_ASSERT(startState != -1);
+
+ // our list of state set that still have to be processed
+ QList< QSet<StateId> > workStates;
+
+ // add the start state to the list of to processed state sets
+ workStates.append(epsilonClosure(QSet<StateId>() << startState));
+
+ while (!workStates.isEmpty()) { // as long as there are state sets to process left
+
+ // enqueue set of states
+ const QSet<StateId> states = workStates.takeFirst();
+
+ if (isMarked.contains(states)) // we processed this state set already
+ continue;
+
+ // mark as processed
+ isMarked.append(states);
+
+ // select a list of all inputs that are possible for
+ // the 'states' set
+ QList<TransitionType> input;
+
+ {
+ QSetIterator<StateId> it(states);
+ while (it.hasNext()) {
+ input << m_transitions.value(it.next()).keys();
+ }
+ }
+
+ // get the state in DFA that corresponds to the 'states' set in the NFA
+ const StateId dfaBegin = dfaStateForNfaState(states, table, dfa);
+
+ for (int i = 0; i < input.count(); ++i) { // for each possible input
+ // retrieve the states that can be reached from the 'states' set by the
+ // given input or by epsilon transition
+ const QSet<StateId> followStates = epsilonClosure(move(states, input.at(i)));
+
+ // get the state in DFA that corresponds to the 'followStates' set in the NFA
+ const StateId dfaEnd = dfaStateForNfaState(followStates, table, dfa);
+
+ // adds a new transition to the DFA that corresponds to the transitions between
+ // 'states' and 'followStates' in the NFA
+ dfa.addTransition(dfaBegin, input.at(i), dfaEnd);
+
+ // add the 'followStates' to the list of to be processed state sets
+ workStates.append(followStates);
+ }
+ }
+
+ return dfa;
+}
+
+template <typename TransitionType>
+QHash<typename XsdStateMachine<TransitionType>::StateId, typename XsdStateMachine<TransitionType>::StateType> XsdStateMachine<TransitionType>::states() const
+{
+ return m_states;
+}
diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h
new file mode 100644
index 0000000..62c6ab0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdStateMachine_H
+#define Patternist_XsdStateMachine_H
+
+#include "qnamepool_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QTextStream>
+
+class QIODevice;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A state machine used for evaluation.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ template <typename TransitionType>
+ class XsdStateMachine
+ {
+ public:
+ typedef qint32 StateId;
+
+ /**
+ * Describes the type of state.
+ */
+ enum StateType
+ {
+ StartState, ///< The state the machine will start with.
+ StartEndState, ///< The state the machine will start with, can be end state as well.
+ InternalState, ///< Any state that is not start or end state.
+ EndState ///< Any state where the machine is allowed to stop.
+ };
+
+ /**
+ * Creates a new state machine object.
+ */
+ XsdStateMachine();
+
+ /**
+ * Creates a new state machine object.
+ *
+ * The name pool to use for accessing object names.
+ */
+ XsdStateMachine(const NamePool::Ptr &namePool);
+
+ /**
+ * Adds a new state of the given @p type to the state machine.
+ *
+ * @return The id of the new state.
+ */
+ StateId addState(StateType type);
+
+ /**
+ * Adds a new @p transition to the state machine.
+ *
+ * @param start The start state.
+ * @param transition The transition to come from the start to the end state.
+ * @param end The end state.
+ */
+ void addTransition(StateId start, TransitionType transition, StateId end);
+
+ /**
+ * Adds a new epsilon @p transition to the state machine.
+ *
+ * @param start The start state.
+ * @param end The end state.
+ */
+ void addEpsilonTransition(StateId start, StateId end);
+
+ /**
+ * Resets the machine to the start state.
+ */
+ void reset();
+
+ /**
+ * Removes all states and transitions from the state machine.
+ */
+ void clear();
+
+ /**
+ * Continues execution of the machine with the given input @p transition.
+ *
+ * @return @c true if the transition was successful, @c false otherwise.
+ */
+ bool proceed(TransitionType transition);
+
+ /**
+ * Returns the list of transitions that are reachable from the current
+ * state.
+ */
+ QList<TransitionType> possibleTransitions() const;
+
+ /**
+ * Continues execution of the machine with the given @p input.
+ *
+ * @note To use this method, inputEqualsTransition must be implemented
+ * to find the right transition to use.
+ *
+ * @return @c true if the transition was successful, @c false otherwise.
+ */
+ template <typename InputType>
+ bool proceed(InputType input);
+
+ /**
+ * Returns whether the given @p input matches the given @p transition.
+ */
+ template <typename InputType>
+ bool inputEqualsTransition(InputType input, TransitionType transition) const;
+
+ /**
+ * Returns whether the machine is in an allowed end state.
+ */
+ bool inEndState() const;
+
+ /**
+ * Returns the last transition that was taken.
+ */
+ TransitionType lastTransition() const;
+
+ /**
+ * Returns the start state of the machine.
+ */
+ StateId startState() const;
+
+ /**
+ * This method should be redefined by template specialization for every
+ * concret TransitionType.
+ */
+ QString transitionTypeToString(TransitionType type) const;
+
+ /**
+ * Outputs the state machine in DOT format to the given
+ * output @p device.
+ */
+ bool outputGraph(QIODevice *device, const QString &graphName) const;
+
+ /**
+ * Returns a DFA that is equal to the NFA of the state machine.
+ */
+ XsdStateMachine<TransitionType> toDFA() const;
+
+ /**
+ * Returns the information of all states of the state machine.
+ */
+ QHash<StateId, StateType> states() const;
+
+ /**
+ * Returns the information of all transitions of the state machine.
+ *
+ * The implementation is inlined in order to workaround a compiler
+ * bug on Symbian/winscw.
+ */
+ QHash<StateId, QHash<TransitionType, QVector<StateId> > > transitions() const
+ {
+ return m_transitions;
+ }
+
+ private:
+ /**
+ * Returns the DFA state for the given @p nfaStat from the given @p stateTable.
+ * If there is no corresponding DFA state yet, a new one is created.
+ */
+ StateId dfaStateForNfaState(QSet<StateId> nfaState, QList< QPair< QSet<StateId>, StateId> > &stateTable, XsdStateMachine<TransitionType> &dfa) const;
+
+ /**
+ * Returns the set of all states that can be reached from the set of @p input states
+ * by the epsilon transition.
+ *
+ * The implementation is inlined in order to workaround a compiler
+ * bug on Symbian/winscw.
+ */
+ QSet<StateId> epsilonClosure(const QSet<StateId> &input) const
+ {
+ // every state can reach itself by epsilon transition, so include the input states
+ // in the result as well
+ QSet<StateId> result = input;
+
+ // add the input states to the list of to be processed states
+ QList<StateId> workStates = input.toList();
+ while (!workStates.isEmpty()) { // while there are states to be processed left...
+
+ // dequeue one state from list
+ const StateId state = workStates.takeFirst();
+
+ // get the list of states that can be reached by the epsilon transition
+ // from the current 'state'
+ const QVector<StateId> targetStates = m_epsilonTransitions.value(state);
+ for (int i = 0; i < targetStates.count(); ++i) {
+ // if we have this target state not in our result set yet...
+ if (!result.contains(targetStates.at(i))) {
+ // ... add it to the result set
+ result.insert(targetStates.at(i));
+
+ // add the target state to the list of to be processed states as well,
+ // as we want to have the epsilon transitions not only for the first
+ // level of following states
+ workStates.append(targetStates.at(i));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the set of all states that can be reached from the set of given @p states
+ * by the given @p input.
+ *
+ * The implementation is inlined in order to workaround a compiler
+ * bug on Symbian/winscw.
+ */
+ QSet<StateId> move(const QSet<StateId> &states, TransitionType input) const
+ {
+ QSet<StateId> result;
+
+ QSetIterator<StateId> it(states);
+ while (it.hasNext()) { // iterate over all given states
+ const StateId state = it.next();
+
+ // get the transition table for the current state
+ const QHash<TransitionType, QVector<StateId> > transitions = m_transitions.value(state);
+
+ // get the target states for the given input
+ const QVector<StateId> targetStates = transitions.value(input);
+
+ // add all target states to the result
+ for (int i = 0; i < targetStates.size(); ++i)
+ result.insert(targetStates.at(i));
+ }
+
+ return result;
+ }
+
+ NamePool::Ptr m_namePool;
+ QHash<StateId, StateType> m_states;
+ QHash<StateId, QHash<TransitionType, QVector<StateId> > > m_transitions;
+ QHash<StateId, QVector<StateId> > m_epsilonTransitions;
+ StateId m_currentState;
+ qint32 m_counter;
+ TransitionType m_lastTransition;
+ };
+
+ #include "qxsdstatemachine.cpp"
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp
new file mode 100644
index 0000000..fed8a41
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdstatemachinebuilder_p.h"
+
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdschemahelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/*
+ * This methods takes a list of objects and returns a list of list
+ * of all combinations the objects can be ordered.
+ *
+ * e.g. input = [ 1, 2, 3 ]
+ * output = [
+ * [ 1, 2, 3 ],
+ * [ 1, 3, 2 ],
+ * [ 2, 1, 3 ],
+ * [ 2, 3, 1 ],
+ * [ 3, 1, 2 ],
+ * [ 3, 2, 1 ]
+ * ]
+ *
+ * The method is used to create all possible combinations for the particles
+ * in an <all> model group.
+ */
+template <typename T>
+QList< QList<T> > allCombinations(const QList<T> &input)
+{
+ if (input.count() == 1)
+ return (QList< QList<T> >() << input);
+
+ QList< QList<T> > result;
+ for (int i = 0; i < input.count(); ++i) {
+ QList<T> subList = input;
+ T value = subList.takeAt(i);
+
+ QList< QList<T> > subLists = allCombinations(subList);
+ for (int j = 0; j < subLists.count(); ++j) {
+ subLists[j].prepend(value);
+ }
+ result << subLists;
+ }
+
+ return result;
+}
+
+XsdStateMachineBuilder::XsdStateMachineBuilder(XsdStateMachine<XsdTerm::Ptr> *machine, const NamePool::Ptr &namePool, Mode mode)
+ : m_stateMachine(machine), m_namePool(namePool), m_mode(mode)
+{
+}
+
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::reset()
+{
+ Q_ASSERT(m_stateMachine);
+
+ m_stateMachine->clear();
+
+ return m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::EndState);
+}
+
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::addStartState(XsdStateMachine<XsdTerm::Ptr>::StateId state)
+{
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::StartState);
+ m_stateMachine->addEpsilonTransition(startState, state);
+
+ return startState;
+}
+
+/*
+ * Create the FSA according to Algorithm Tp(S) from http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html
+ */
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::buildParticle(const XsdParticle::Ptr &particle, XsdStateMachine<XsdTerm::Ptr>::StateId endState)
+{
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentStartState = endState;
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentEndState = endState;
+
+ // 2
+ if (particle->maximumOccursUnbounded()) {
+ const XsdStateMachine<XsdTerm::Ptr>::StateId t = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId n = buildTerm(particle->term(), t);
+
+ m_stateMachine->addEpsilonTransition(t, n);
+ m_stateMachine->addEpsilonTransition(n, endState);
+
+ currentEndState = t;
+ currentStartState = t;
+ } else { // 3
+ int count = (particle->maximumOccurs() - particle->minimumOccurs());
+ if (count > 100)
+ count = 100;
+
+ for (int i = 0; i < count; ++i) {
+ currentStartState = buildTerm(particle->term(), currentEndState);
+ m_stateMachine->addEpsilonTransition(currentStartState, endState);
+ currentEndState = currentStartState;
+ }
+ }
+
+ int minOccurs = particle->minimumOccurs();
+ if (minOccurs > 100)
+ minOccurs = 100;
+
+ for (int i = 0; i < minOccurs; ++i) {
+ currentStartState = buildTerm(particle->term(), currentEndState);
+ currentEndState = currentStartState;
+ }
+
+ return currentStartState;
+}
+
+/*
+ * Create the FSA according to Algorithm Tt(S) from http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html
+ */
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::buildTerm(const XsdTerm::Ptr &term, XsdStateMachine<XsdTerm::Ptr>::StateId endState)
+{
+ if (term->isWildcard()) { // 1
+ const XsdStateMachine<XsdTerm::Ptr>::StateId b = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+ m_stateMachine->addTransition(b, term, endState);
+ return b;
+ } else if (term->isElement()) { // 2
+ const XsdStateMachine<XsdTerm::Ptr>::StateId b = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+ m_stateMachine->addTransition(b, term, endState);
+
+ const XsdElement::Ptr element(term);
+ if (m_mode == CheckingMode) {
+ const XsdElement::List substGroups = element->substitutionGroups();
+ for (int i = 0; i < substGroups.count(); ++i)
+ m_stateMachine->addTransition(b, substGroups.at(i), endState);
+ } else if (m_mode == ValidatingMode) {
+ const XsdElement::List substGroups = element->substitutionGroups();
+ for (int i = 0; i < substGroups.count(); ++i) {
+ if (XsdSchemaHelper::substitutionGroupOkTransitive(element, substGroups.at(i), m_namePool))
+ m_stateMachine->addTransition(b, substGroups.at(i), endState);
+ }
+ }
+
+ return b;
+ } else if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group(term);
+
+ if (group->compositor() == XsdModelGroup::ChoiceCompositor) { // 3
+ const XsdStateMachine<XsdTerm::Ptr>::StateId b = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+
+ for (int i = 0; i < group->particles().count(); ++i) {
+ const XsdParticle::Ptr particle(group->particles().at(i));
+ if (particle->maximumOccurs() != 0) {
+ const XsdStateMachine<XsdTerm::Ptr>::StateId state = buildParticle(particle, endState);
+ m_stateMachine->addEpsilonTransition(b, state);
+ }
+ }
+
+ return b;
+ } else if (group->compositor() == XsdModelGroup::SequenceCompositor) { // 4
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentStartState = endState;
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentEndState = endState;
+
+ for (int i = (group->particles().count() - 1); i >= 0; --i) { // iterate reverse
+ const XsdParticle::Ptr particle(group->particles().at(i));
+ if (particle->maximumOccurs() != 0) {
+ currentStartState = buildParticle(particle, currentEndState);
+ currentEndState = currentStartState;
+ }
+ }
+
+ return currentStartState;
+ } else if (group->compositor() == XsdModelGroup::AllCompositor) {
+ const XsdStateMachine<XsdTerm::Ptr>::StateId newStartState = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+
+ const QList<XsdParticle::List> list = allCombinations(group->particles());
+
+ for (int i = 0; i < list.count(); ++i) {
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentStartState = endState;
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentEndState = endState;
+
+ const XsdParticle::List particles = list.at(i);
+ for (int j = (particles.count() - 1); j >= 0; --j) { // iterate reverse
+ const XsdParticle::Ptr particle(particles.at(j));
+ if (particle->maximumOccurs() != 0) {
+ currentStartState = buildParticle(particle, currentEndState);
+ currentEndState = currentStartState;
+ }
+ }
+ m_stateMachine->addEpsilonTransition(newStartState, currentStartState);
+ }
+
+ if (list.isEmpty())
+ return endState;
+ else
+ return newStartState;
+ }
+ }
+
+ Q_ASSERT(false);
+ return 0;
+}
+
+static void internalParticleLookupMap(const XsdParticle::Ptr &particle, QHash<XsdTerm::Ptr, XsdParticle::Ptr> &hash)
+{
+ hash.insert(particle->term(), particle);
+
+ if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i)
+ internalParticleLookupMap(particles.at(i), hash);
+ }
+}
+
+QHash<XsdTerm::Ptr, XsdParticle::Ptr> XsdStateMachineBuilder::particleLookupMap(const XsdParticle::Ptr &particle)
+{
+ QHash<XsdTerm::Ptr, XsdParticle::Ptr> result;
+ internalParticleLookupMap(particle, result);
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h
new file mode 100644
index 0000000..c17ca9b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdStateMachineBuilder_H
+#define Patternist_XsdStateMachineBuilder_H
+
+#include "qxsdparticle_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdterm_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class to build up validation state machines.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdStateMachineBuilder : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdStateMachineBuilder> Ptr;
+
+ enum Mode
+ {
+ CheckingMode,
+ ValidatingMode
+ };
+
+ /**
+ * Creates a new state machine builder.
+ *
+ * @param machine The state machine it should work on.
+ * @param namePool The name pool used by all schema components.
+ * @param mode The mode the machine shall be build for.
+ */
+ XsdStateMachineBuilder(XsdStateMachine<XsdTerm::Ptr> *machine, const NamePool::Ptr &namePool, Mode mode = CheckingMode);
+
+ /**
+ * Resets the state machine.
+ *
+ * @returns The initial end state.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId reset();
+
+ /**
+ * Prepends a start state to the given @p state.
+ * That is needed to allow the conversion of the state machine from a FSA to a DFA.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId addStartState(XsdStateMachine<XsdTerm::Ptr>::StateId state);
+
+ /**
+ * Creates the state machine for the given @p particle that should have the
+ * given @p endState.
+ *
+ * @returns The new start state.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId buildParticle(const XsdParticle::Ptr &particle, XsdStateMachine<XsdTerm::Ptr>::StateId endState);
+
+ /**
+ * Creates the state machine for the given @p term that should have the
+ * given @p endState.
+ *
+ * @returns The new start state.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId buildTerm(const XsdTerm::Ptr &term, XsdStateMachine<XsdTerm::Ptr>::StateId endState);
+
+ /**
+ * Returns a hash that maps each term that appears inside @p particle, to the particle it belongs.
+ *
+ * @note These information are used by XsdParticleChecker to check particle inheritance.
+ */
+ static QHash<XsdTerm::Ptr, XsdParticle::Ptr> particleLookupMap(const XsdParticle::Ptr &particle);
+
+ private:
+ XsdStateMachine<XsdTerm::Ptr> *m_stateMachine;
+ NamePool::Ptr m_namePool;
+ Mode m_mode;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdterm.cpp b/src/xmlpatterns/schema/qxsdterm.cpp
new file mode 100644
index 0000000..19af613
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdterm.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdterm_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdTerm::isElement() const
+{
+ return false;
+}
+
+bool XsdTerm::isModelGroup() const
+{
+ return false;
+}
+
+bool XsdTerm::isWildcard() const
+{
+ return false;
+}
+
+bool XsdTerm::isReference() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdterm_p.h b/src/xmlpatterns/schema/qxsdterm_p.h
new file mode 100644
index 0000000..6b3f66a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdterm_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdTerm_H
+#define Patternist_XsdTerm_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A base class for all particles of a model group.
+ *
+ * This class is the base class for all particles of a model group
+ * as the <em>element</em>, <em>group</em> or <em>any</em> tag, it is not supposed to
+ * be instantiated directly.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSTerm">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdTerm : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdTerm> Ptr;
+
+ /**
+ * Returns @c true if the term is an element, @c false otherwise.
+ */
+ virtual bool isElement() const;
+
+ /**
+ * Returns @c true if the term is a model group (group tag), @c false otherwise.
+ */
+ virtual bool isModelGroup() const;
+
+ /**
+ * Returns @c true if the term is a wildcard (any tag), @c false otherwise.
+ */
+ virtual bool isWildcard() const;
+
+ /**
+ * Returns @c true if the term is a reference, @c false otherwise.
+ *
+ * @note The reference term is only used internally as helper during type resolving.
+ */
+ virtual bool isReference() const;
+
+ protected:
+ /**
+ * This constructor only exists to ensure this class is subclassed.
+ */
+ inline XsdTerm() {};
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdtypechecker.cpp b/src/xmlpatterns/schema/qxsdtypechecker.cpp
new file mode 100644
index 0000000..217932e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdtypechecker.cpp
@@ -0,0 +1,1339 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdtypechecker_p.h"
+
+#include "qabstractdatetime_p.h"
+#include "qbase64binary_p.h"
+#include "qboolean_p.h"
+#include "qdecimal_p.h"
+#include "qderivedinteger_p.h"
+#include "qduration_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qhexbinary_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qpatternplatform_p.h"
+#include "qqnamevalue_p.h"
+#include "qvaluefactory_p.h"
+#include "qxmlnamepool.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemamerger_p.h"
+#include "qxsdstatemachine_p.h"
+
+#include "qxsdschemadebugger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaSourceLocationReflection::XsdSchemaSourceLocationReflection(const QSourceLocation &location)
+ : m_sourceLocation(location)
+{
+}
+
+const SourceLocationReflection* XsdSchemaSourceLocationReflection::actualReflection() const
+{
+ return this;
+}
+
+QSourceLocation XsdSchemaSourceLocationReflection::sourceLocation() const
+{
+ return m_sourceLocation;
+}
+
+
+static AnySimpleType::Ptr comparableType(const AnySimpleType::Ptr &type)
+{
+ if (!type->isDefinedBySchema()) {
+ return type;
+ } else {
+ const XsdSimpleType::Ptr simpleType(type);
+ if (type->category() == SchemaType::SimpleTypeAtomic) {
+ return simpleType->primitiveType();
+ } else if (type->category() == SchemaType::SimpleTypeList) {
+ return simpleType->itemType();
+ } else if (type->category() == SchemaType::SimpleTypeUnion) {
+ return simpleType->memberTypes().first();
+ }
+ }
+
+ Q_ASSERT(false);
+ return AnySimpleType::Ptr();
+}
+
+static int totalDigitsForSignedLongLong(long long value)
+{
+ QString number = QString::number(value);
+ if (number.startsWith(QLatin1Char('-')))
+ number = number.mid(1);
+
+ return number.length();
+}
+
+static int totalDigitsForUnsignedLongLong(unsigned long long value)
+{
+ const QString number = QString::number(value);
+ return number.length();
+}
+
+static int totalDigitsForDecimal(const QString &lexicalValue)
+{
+ const QLatin1Char zeroChar('0');
+ const int length = lexicalValue.length() - 1;
+
+ // strip leading zeros
+ int pos = 0;
+ while (lexicalValue.at(pos) == zeroChar && (pos != length))
+ pos++;
+
+ QString value = lexicalValue.mid(pos);
+
+ // if contains '.' strip trailing zeros
+ if (value.contains(QLatin1Char('.'))) {
+ pos = value.length() - 1;
+ while (value.at(pos) == zeroChar) {
+ pos--;
+ }
+
+ value = value.left(pos + 1);
+ }
+
+ // check number of digits of remaining string
+ int totalDigits = 0;
+ for (int i = 0; i < value.count(); ++i)
+ if (value.at(i).isDigit())
+ ++totalDigits;
+
+ if (totalDigits == 0)
+ totalDigits = 1;
+
+ return totalDigits;
+}
+
+static int fractionDigitsForDecimal(const QString &lexicalValue)
+{
+ // we use the lexical value here, as the conversion to double might strip
+ // away decimal positions
+
+ QString trimmedValue(lexicalValue.trimmed());
+ const int pos = trimmedValue.indexOf(QLatin1Char('.'));
+ if (pos == -1) // no '.' -> 0 fraction digits
+ return 0;
+ else
+ return (trimmedValue.length() - pos - 1);
+}
+
+XsdTypeChecker::XsdTypeChecker(const XsdSchemaContext::Ptr &context, const QVector<QXmlName> &namespaceBindings, const QSourceLocation &location)
+ : m_context(context)
+ , m_namePool(m_context->namePool())
+ , m_namespaceBindings(namespaceBindings)
+ , m_reflection(new XsdSchemaSourceLocationReflection(location))
+{
+}
+
+XsdTypeChecker::~XsdTypeChecker()
+{
+ delete m_reflection;
+}
+
+QString XsdTypeChecker::normalizedValue(const QString &value, const XsdFacet::Hash &facets)
+{
+ if (!facets.contains(XsdFacet::WhiteSpace))
+ return value;
+
+ const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace);
+
+ const DerivedString<TypeString>::Ptr facetValue = whiteSpaceFacet->value();
+ const QString stringValue = facetValue->stringValue();
+ if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Preserve))
+ return value;
+ else if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
+ QString newValue(value);
+ newValue.replace(QLatin1Char('\t'), QLatin1Char(' '));
+ newValue.replace(QLatin1Char('\n'), QLatin1Char(' '));
+ newValue.replace(QLatin1Char('\r'), QLatin1Char(' '));
+
+ return newValue;
+ } else if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Collapse)) {
+ return value.simplified();
+ }
+
+ return value;
+}
+
+XsdFacet::Hash XsdTypeChecker::mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
+{
+ if (!type)
+ return XsdFacet::Hash();
+
+ const XsdFacet::Hash baseFacets = mergedFacetsForType(type->wxsSuperType(), context);
+ const XsdFacet::Hash facets = context->facetsForType(type);
+
+ XsdFacet::Hash result = baseFacets;
+ XsdFacet::HashIterator it(facets);
+ while (it.hasNext()) {
+ it.next();
+
+ result.insert(it.key(), it.value());
+ }
+
+ return result;
+}
+
+bool XsdTypeChecker::isValidString(const QString &normalizedString, const AnySimpleType::Ptr &type, QString &errorMsg, AnySimpleType::Ptr *boundType) const
+{
+ if (type->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ if (boundType)
+ *boundType = type;
+
+ return true;
+ }
+
+ if (!type->isDefinedBySchema()) {
+ // special QName check
+ if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ if (!XPathHelper::isQName(normalizedString)) {
+ errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2.").arg(formatData(normalizedString)).arg(formatType(m_namePool, type));
+ return false;
+ }
+ }
+
+ const AtomicValue::Ptr value = fromLexical(normalizedString, type, m_context, m_reflection);
+ if (value->hasError()) {
+ errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2.").arg(formatData(normalizedString)).arg(formatType(m_namePool, type));
+ return false;
+ }
+
+ if (!checkConstrainingFacets(value, normalizedString, type, errorMsg)) {
+ return false;
+ }
+
+ if (boundType)
+ *boundType = type;
+
+ } else {
+ const XsdSimpleType::Ptr simpleType(type);
+
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ AnySimpleType::Ptr targetType = simpleType->primitiveType();
+ if (!simpleType->wxsSuperType()->isDefinedBySchema())
+ targetType = simpleType->wxsSuperType();
+
+ const AtomicValue::Ptr value = fromLexical(normalizedString, targetType, m_context, m_reflection);
+ if (value->hasError()) {
+ errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2.").arg(formatData(normalizedString)).arg(formatType(m_namePool, targetType));
+ return false;
+ }
+
+ if (!checkConstrainingFacets(value, normalizedString, type, errorMsg)) {
+ return false;
+ }
+
+ if (boundType)
+ *boundType = type;
+
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ QStringList entries = normalizedString.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < entries.count(); ++i) {
+ entries[i] = normalizedValue(entries.at(i), mergedFacetsForType(simpleType->itemType(), m_context));
+ }
+
+ if (!checkConstrainingFacetsList(entries, normalizedString, simpleType->itemType(), mergedFacetsForType(simpleType, m_context), errorMsg)) {
+ return false;
+ }
+
+ for (int i = 0; i < entries.count(); ++i) {
+ if (!isValidString(entries.at(i), simpleType->itemType(), errorMsg)) {
+ return false;
+ }
+ }
+
+ if (boundType)
+ *boundType = simpleType->itemType();
+
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ if (!checkConstrainingFacetsUnion(normalizedString, normalizedString, simpleType, mergedFacetsForType(simpleType, m_context), errorMsg)) {
+ return false;
+ }
+
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ bool foundValidType = false;
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const XsdFacet::Hash mergedFacets = mergedFacetsForType(memberTypes.at(i), m_context);
+ if (isValidString(normalizedValue(normalizedString, mergedFacets), memberTypes.at(i), errorMsg)) {
+ foundValidType = true;
+
+ if (boundType)
+ *boundType = memberTypes.at(i);
+
+ break;
+ }
+ }
+
+ if (!foundValidType) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::valuesAreEqual(const QString &value, const QString &otherValue, const AnySimpleType::Ptr &type) const
+{
+ const AnySimpleType::Ptr targetType = comparableType(type);
+
+ // if the type is xs:anySimpleType we just do string comparison...
+ if (targetType->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool))
+ return (value == otherValue);
+
+ if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ const QXmlName valueName = convertToQName(value);
+ const QXmlName otherValueName = convertToQName(otherValue);
+
+ if (valueName == otherValueName)
+ return true;
+ }
+
+ if (type->category() == SchemaType::SimpleTypeAtomic) {
+ // ... otherwise we use the casting platform for value comparison
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ const DerivedString<TypeString>::Ptr otherValueStr = DerivedString<TypeString>::fromLexical(m_namePool, otherValue);
+
+ return XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, otherValueStr, targetType, m_context, m_reflection);
+ } else if (type->category() == SchemaType::SimpleTypeList) {
+ const QStringList values = value.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ const QStringList otherValues = otherValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ if (values.count() != otherValues.count())
+ return false;
+
+ for (int i = 0; i < values.count(); ++i) {
+ if (!valuesAreEqual(values.at(i), otherValues.at(i), XsdSimpleType::Ptr(type)->itemType()))
+ return false;
+ }
+
+ return true;
+ } else if (type->category() == SchemaType::SimpleTypeUnion) {
+ const AnySimpleType::List memberTypes = XsdSimpleType::Ptr(type)->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ if (valuesAreEqual(value, otherValue, memberTypes.at(i))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return false;
+}
+
+bool XsdTypeChecker::checkConstrainingFacets(const AtomicValue::Ptr &value, const QString &lexicalValue, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ const XsdFacet::Hash facets = mergedFacetsForType(type, m_context);
+
+ if (BuiltinTypes::xsString->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUntypedAtomic->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsString(value->stringValue(), facets, BuiltinTypes::xsString, errorMsg);
+ } else if (BuiltinTypes::xsAnyURI->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsString(value->stringValue(), facets, BuiltinTypes::xsAnyURI, errorMsg);
+ } else if (BuiltinTypes::xsNOTATION->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsNotation(value->as<QNameValue>()->qName(), facets, errorMsg);
+ } else if (BuiltinTypes::xsUnsignedByte->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUnsignedInt->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUnsignedLong->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUnsignedShort->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsUnsignedInteger(value->as<Numeric>()->toUnsignedInteger(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsInteger->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsSignedInteger(value->as<Numeric>()->toInteger(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsFloat->wxsTypeMatches(type) ||
+ BuiltinTypes::xsDouble->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDouble(value->as<Numeric>()->toDouble(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsDecimal->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDecimal(value, lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsDateTime->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsDateTime, errorMsg);
+ } else if (BuiltinTypes::xsDate->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsDate, errorMsg);
+ } else if (BuiltinTypes::xsGYear->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGYear, errorMsg);
+ } else if (BuiltinTypes::xsGYearMonth->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGYearMonth, errorMsg);
+ } else if (BuiltinTypes::xsGMonth->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGMonth, errorMsg);
+ } else if (BuiltinTypes::xsGMonthDay->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGMonthDay, errorMsg);
+ } else if (BuiltinTypes::xsGDay->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGDay, errorMsg);
+ } else if (BuiltinTypes::xsTime->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsTime, errorMsg);
+ } else if (BuiltinTypes::xsDuration->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDuration(value, lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsBoolean->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsBoolean(value->as<Boolean>()->value(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsHexBinary->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsBinary(value->as<Base64Binary>()->asByteArray(), facets, BuiltinTypes::xsHexBinary, errorMsg);
+ } else if (BuiltinTypes::xsBase64Binary->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsBinary(value->as<Base64Binary>()->asByteArray(), facets, BuiltinTypes::xsBase64Binary, errorMsg);
+ } else if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsQName(value->as<QNameValue>()->qName(), lexicalValue, facets, errorMsg);
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsString(const QString &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Length);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() != value.length()) {
+ errorMsg = QtXmlPatterns::tr("String content does not match the length facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() > value.length()) {
+ errorMsg = QtXmlPatterns::tr("String content does not match the minLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() < value.length()) {
+ errorMsg = QtXmlPatterns::tr("String content does not match the maxLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(value)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("String content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, value);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), type, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("String content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsSignedInteger(long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() < value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() <= value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() > value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() >= value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, QString::number(value));
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsLong, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (totalDigitsForSignedLongLong(value) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match in the totalDigits facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsUnsignedInteger(unsigned long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() < value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() <= value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() > value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() >= value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, QString::number(value));
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsUnsignedLong, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (totalDigitsForUnsignedLongLong(value) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match in the totalDigits facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDouble(double value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() < value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() <= value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() > value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() >= value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, QString::number(value));
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsDouble, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Double content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDecimal(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::FractionDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::FractionDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (fractionDigitsForDecimal(lexicalValue) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Decimal content does not match in the fractionDigits facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (totalDigitsForDecimal(lexicalValue) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Decimal content does not match in the totalDigits facet.");
+ return false;
+ }
+ }
+
+ return checkConstrainingFacetsDouble(value->as<Decimal>()->toDouble(), lexicalValue, facets, errorMsg);
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDateTime(const QDateTime &value, const QString &lexicalValue, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() < value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() <= value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() > value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() >= value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() == value) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Date time content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match pattern facet.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDuration(const AtomicValue::Ptr&, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MaximumInclusive)->value(), AtomicComparator::OperatorLessThan, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MaximumExclusive)->value(), AtomicComparator::OperatorLessOrEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MinimumInclusive)->value(), AtomicComparator::OperatorGreaterThan, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MinimumExclusive)->value(), AtomicComparator::OperatorGreaterOrEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(multiValue.at(j), AtomicComparator::OperatorEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Duration content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsBoolean(bool, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Boolean content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsBinary(const QByteArray &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Length);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() != value.length()) {
+ errorMsg = QtXmlPatterns::tr("Binary content does not match the length facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() > value.length()) {
+ errorMsg = QtXmlPatterns::tr("Binary content does not match the minLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() < value.length()) {
+ errorMsg = QtXmlPatterns::tr("Binary content does not match the maxLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const Base64Binary::Ptr binary = ValueFactory::fromLexical(multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ const QByteArray facetValue = binary->as<Base64Binary>()->asByteArray();
+ if (value == facetValue) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Binary content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ //TODO: implement
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsQName(const QXmlName &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ // always true
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ // always true
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ // always true
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ if (!XPathHelper::isQName(lexicalValue)) {
+ errorMsg = QtXmlPatterns::tr("Invalid QName content: %1.").arg(formatData(lexicalValue));
+ return false;
+ }
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QXmlName facetValue = multiValue.at(j)->as<QNameValue>()->qName();
+
+ if (value == facetValue) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("QName content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("QName content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsNotation(const QXmlName &value, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ // deprecated by spec
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ // deprecated by spec
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ // deprecated by spec
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QXmlName facetValue = multiValue.at(j)->as<QNameValue>()->qName();
+
+ if (value == facetValue) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Notation content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ //TODO: implement
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsList(const QStringList &values, const QString &lexicalValue, const AnySimpleType::Ptr &itemType, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr value = facets.value(XsdFacet::Length)->value();
+ if (value->toInteger() != values.count()) {
+ errorMsg = QtXmlPatterns::tr("List content does not match length facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr value = facets.value(XsdFacet::MinimumLength)->value();
+ if (value->toInteger() > values.count()) {
+ errorMsg = QtXmlPatterns::tr("List content does not match minLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr value = facets.value(XsdFacet::MaximumLength)->value();
+ if (value->toInteger() < values.count()) {
+ errorMsg = QtXmlPatterns::tr("List content does not match maxLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+
+ bool found = false;
+
+ // we have to handle lists with QName derived items differently
+ if (BuiltinTypes::xsQName->wxsTypeMatches(itemType) || BuiltinTypes::xsNOTATION->wxsTypeMatches(itemType)) {
+ // first convert the string values from the instance document to a list of QXmlName
+ QList<QXmlName> instanceValues;
+ for (int i = 0; i < values.count(); ++i) {
+ instanceValues.append(convertToQName(values.at(i)));
+ }
+
+ // fetch the values from the facet and create a list of QXmlNames for each of them
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int i = 0; i < multiValue.count(); ++i) {
+ const QStringList facetValueList = multiValue.at(i)->as<DerivedString<TypeString> >()->stringValue().split(QLatin1Char(' '), QString::SkipEmptyParts);
+
+ // create the list of atomic string values
+ QList<QXmlName> facetValues;
+ for (int j = 0; j < facetValueList.count(); ++j) {
+ facetValues.append(convertToQName(facetValueList.at(j)));
+ }
+
+ // check if both lists have the same length
+ if (instanceValues.count() != facetValues.count())
+ continue;
+
+ // check if both lists are equal, that means the contain equal items in the same order
+ bool matchesAll = true;
+ for (int j = 0; j < instanceValues.count(); ++j) {
+ if (instanceValues.at(j) != facetValues.at(j)) {
+ matchesAll = false;
+ break;
+ }
+ }
+
+ if (matchesAll) {
+ found = true;
+ break;
+ }
+ }
+ } else {
+ // first convert the string values from the instance document to atomic values of type string
+ AtomicValue::List instanceValues;
+ for (int i = 0; i < values.count(); ++i) {
+ instanceValues.append(DerivedString<TypeString>::fromLexical(m_namePool, values.at(i)));
+ }
+
+ // fetch the values from the facet and create a list of atomic string values for each of them
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ const AnySimpleType::Ptr targetType = comparableType(itemType);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int i = 0; i < multiValue.count(); ++i) {
+ const QStringList facetValueList = multiValue.at(i)->as<DerivedString<TypeString> >()->stringValue().split(QLatin1Char(' '), QString::SkipEmptyParts);
+
+ // create the list of atomic string values
+ AtomicValue::List facetValues;
+ for (int j = 0; j < facetValueList.count(); ++j) {
+ facetValues.append(DerivedString<TypeString>::fromLexical(m_namePool, facetValueList.at(j)));
+ }
+
+ // check if both lists have the same length
+ if (instanceValues.count() != facetValues.count())
+ continue;
+
+ // check if both lists are equal, that means the contain equal items in the same order
+ bool matchesAll = true;
+ for (int j = 0; j < instanceValues.count(); ++j) {
+ if (!XsdSchemaHelper::constructAndCompare(instanceValues.at(j), AtomicComparator::OperatorEqual, facetValues.at(j), targetType, m_context, m_reflection)) {
+ matchesAll = false;
+ break;
+ }
+ }
+
+ if (matchesAll) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("List content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("List content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsUnion(const QString &value, const QString &lexicalValue, const XsdSimpleType::Ptr &simpleType, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ // convert the instance value into an atomic string value
+ const DerivedString<TypeString>::Ptr valueString = DerivedString<TypeString>::fromLexical(m_namePool, value);
+
+ // collect the facet values into a list of atomic string values
+ const AtomicValue::List facetValues = facet->multiValue();
+
+ // compare the instance value against the facetValues for each member type and
+ // search for a match
+
+ bool found = false;
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr targetType = comparableType(memberTypes.at(i));
+ for (int j = 0; j < facetValues.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueString, AtomicComparator::OperatorEqual, facetValues.at(j), targetType, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Union content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Union content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+AtomicValue::Ptr XsdTypeChecker::fromLexical(const QString &value, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
+{
+ if (type->name(m_namePool) == BuiltinTypes::xsNOTATION->name(m_namePool) || type->name(m_namePool) == BuiltinTypes::xsQName->name(m_namePool)) {
+ if (value.simplified().isEmpty())
+ return ValidationError::createError(QtXmlPatterns::tr("Data of type %1 are not allowed to be empty.").arg(formatType(m_namePool, BuiltinTypes::xsNOTATION)));
+
+ const QXmlName valueName = convertToQName(value);
+ return QNameValue::fromValue(m_namePool, valueName);
+ } else {
+ return ValueFactory::fromLexical(value, type, context, reflection);
+ }
+}
+
+QXmlName XsdTypeChecker::convertToQName(const QString &name) const
+{
+ const int pos = name.indexOf(QLatin1Char(':'));
+
+ QXmlName::PrefixCode prefixCode = 0;
+ QXmlName::NamespaceCode namespaceCode;
+ QXmlName::LocalNameCode localNameCode;
+ if (pos != -1) {
+ prefixCode = m_context->namePool()->allocatePrefix(name.left(pos));
+ namespaceCode = StandardNamespaces::empty;
+ for (int i = 0; i < m_namespaceBindings.count(); ++i) {
+ if (m_namespaceBindings.at(i).prefix() == prefixCode) {
+ namespaceCode = m_namespaceBindings.at(i).namespaceURI();
+ break;
+ }
+ }
+ localNameCode = m_context->namePool()->allocateLocalName(name.mid(pos + 1));
+ } else {
+ prefixCode = StandardPrefixes::empty;
+ namespaceCode = StandardNamespaces::empty;
+ for (int i = 0; i < m_namespaceBindings.count(); ++i) {
+ if (m_namespaceBindings.at(i).prefix() == prefixCode) {
+ namespaceCode = m_namespaceBindings.at(i).namespaceURI();
+ break;
+ }
+ }
+ localNameCode = m_context->namePool()->allocateLocalName(name);
+ }
+
+ return QXmlName(namespaceCode, localNameCode, prefixCode);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdtypechecker_p.h b/src/xmlpatterns/schema/qxsdtypechecker_p.h
new file mode 100644
index 0000000..ae90bdc
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdtypechecker_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdTypeChecker_H
+#define Patternist_XsdTypeChecker_H
+
+#include <QtXmlPatterns/QSourceLocation>
+
+#include "qschematype_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qxsdschemacontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlQuery;
+
+namespace QPatternist
+{
+ /**
+ * @short An implementation of SourceLocationReflection that takes a QSourceLocation.
+ *
+ * This is a convenience class which provides a QSourceLocation with a SourceLocationReflection
+ * interface.
+ */
+ class XsdSchemaSourceLocationReflection : public SourceLocationReflection
+ {
+ public:
+ XsdSchemaSourceLocationReflection(const QSourceLocation &location);
+
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual QSourceLocation sourceLocation() const;
+
+ private:
+ const QSourceLocation m_sourceLocation;
+ };
+
+ /**
+ * @short The class that provides methods for checking a string against a type.
+ *
+ * The class provides functionality for type-aware string handling.
+ */
+ class XsdTypeChecker
+ {
+ public:
+ /**
+ * Creates a new type checker.
+ *
+ * @param context The schema context that is used for error reporting.
+ * @param namespaceBindings The namespace bindings that shall be used to check against xs:QName based types.
+ * @param location The source location that is used for error reporting.
+ */
+ XsdTypeChecker(const XsdSchemaContext::Ptr &context, const QVector<QXmlName> &namespaceBindings, const QSourceLocation &location);
+
+ /**
+ * Destroys the type checker.
+ */
+ ~XsdTypeChecker();
+
+ /**
+ * Returns all facets for the given @p type.
+ *
+ * The list of facets is created by following the type hierarchy from xs:anyType down to the given type
+ * and merging the facets in each step.
+ */
+ static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context);
+
+ /**
+ * Returns the normalized value for the given @p value.
+ *
+ * The normalized value is the original value with all the white space facets
+ * applied on it.
+ *
+ * @param value The original value.
+ * @param facets The hash of all facets of the values type.
+ */
+ static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets);
+
+ /**
+ * Checks whether the @p normalizedString is valid according the given @p type.
+ *
+ * @param normalizedString The string in normalized form (whitespace facets applied).
+ * @param type The type the string shall be tested against.
+ * @param errorMsg Contains the error message if the normalizedString does not match the type.
+ * @param boundType The type the data was bound to during validation.
+ *
+ * @note The @p boundType only differs from @p type if the type is derived from an based union value.
+ */
+ bool isValidString(const QString &normalizedString, const AnySimpleType::Ptr &type, QString &errorMsg, AnySimpleType::Ptr *boundType = 0) const;
+
+ /**
+ * Returns whether the given @p value and @p otherValue are of @p type and are equal.
+ */
+ bool valuesAreEqual(const QString &value, const QString &otherValue, const AnySimpleType::Ptr &type) const;
+
+ private:
+ Q_DISABLE_COPY(XsdTypeChecker)
+
+ /**
+ * Checks the given value against the facets of @p type.
+ */
+ bool checkConstrainingFacets(const AtomicValue::Ptr &value, const QString &lexicalValue, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsString(const QString &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsSignedInteger(long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsUnsignedInteger(unsigned long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsDouble(double value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsDecimal(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsDateTime(const QDateTime &value, const QString &lexicalValue, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsDuration(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsBoolean(bool value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsBinary(const QByteArray &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsQName(const QXmlName&, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsNotation(const QXmlName &value, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsList(const QStringList &values, const QString &lexicalValue, const AnySimpleType::Ptr &itemType, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsUnion(const QString &value, const QString &lexicalValue, const XsdSimpleType::Ptr &simpleType, const XsdFacet::Hash &facets, QString &errorMsg) const;
+
+ /**
+ * Creates an atomic value of @p type from the given string @p value.
+ */
+ AtomicValue::Ptr fromLexical(const QString &value, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Converts a qualified name into a QXmlName according to the namespace
+ * mappings of the current node.
+ */
+ QXmlName convertToQName(const QString &name) const;
+
+ XsdSchemaContext::Ptr m_context;
+ XsdSchema::Ptr m_schema;
+ const NamePool::Ptr m_namePool;
+ QVector<QXmlName> m_namespaceBindings;
+ SourceLocationReflection* m_reflection;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsduserschematype.cpp b/src/xmlpatterns/schema/qxsduserschematype.cpp
new file mode 100644
index 0000000..95892e1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsduserschematype.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * NOTE: This file is included by qxsduserschematype_p.h
+ * if you need some includes, put them in qxsduserschematype_p.h (outside of the namespace)
+ */
+
+template<typename TSuperClass>
+void XsdUserSchemaType<TSuperClass>::setName(const QXmlName &name)
+{
+ m_name = name;
+}
+
+template<typename TSuperClass>
+QXmlName XsdUserSchemaType<TSuperClass>::name(const NamePool::Ptr&) const
+{
+ return m_name;
+}
+
+template<typename TSuperClass>
+QString XsdUserSchemaType<TSuperClass>::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(m_name);
+}
+
+template<typename TSuperClass>
+void XsdUserSchemaType<TSuperClass>::setDerivationConstraints(const SchemaType::DerivationConstraints &constraints)
+{
+ m_derivationConstraints = constraints;
+}
+
+template<typename TSuperClass>
+SchemaType::DerivationConstraints XsdUserSchemaType<TSuperClass>::derivationConstraints() const
+{
+ return m_derivationConstraints;
+}
diff --git a/src/xmlpatterns/schema/qxsduserschematype_p.h b/src/xmlpatterns/schema/qxsduserschematype_p.h
new file mode 100644
index 0000000..72162d5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsduserschematype_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdUserSchemaType_H
+#define Patternist_XsdUserSchemaType_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qschematype_p.h"
+#include "qxsdannotated_p.h"
+
+template<typename N, typename M> class QHash;
+template<typename N> class QList;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A base class for all user defined simple and complex types.
+ *
+ * This class was introduced to combine the SchemaType class and the
+ * NamedSchemaComponent class without explicit inheritance.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ template<typename TSuperClass>
+ class XsdUserSchemaType : public TSuperClass, public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdUserSchemaType> Ptr;
+
+ /**
+ * Sets the @p name of the type.
+ */
+ void setName(const QXmlName &name);
+
+ /**
+ * Returns the name of the type.
+ *
+ * @param namePool The pool the name belongs to.
+ */
+ virtual QXmlName name(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Returns the display name of the type.
+ *
+ * @param namePool The pool the name belongs to.
+ */
+ virtual QString displayName(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Sets the derivation @p constraints of the type.
+ */
+ void setDerivationConstraints(const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * Returns the derivation constraints of the type.
+ */
+ SchemaType::DerivationConstraints derivationConstraints() const;
+
+ private:
+ QXmlName m_name;
+ SchemaType::DerivationConstraints m_derivationConstraints;
+ };
+
+ #include "qxsduserschematype.cpp"
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp
new file mode 100644
index 0000000..3cbb6c1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdvalidatedxmlnodemodel_p.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdValidatedXmlNodeModel::XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model)
+ : m_internalModel(model)
+{
+}
+
+XsdValidatedXmlNodeModel::~XsdValidatedXmlNodeModel()
+{
+}
+
+QUrl XsdValidatedXmlNodeModel::baseUri(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->baseUri(index);
+}
+
+QUrl XsdValidatedXmlNodeModel::documentUri(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->documentUri(index);
+}
+
+QXmlNodeModelIndex::NodeKind XsdValidatedXmlNodeModel::kind(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->kind(index);
+}
+
+QXmlNodeModelIndex::DocumentOrder XsdValidatedXmlNodeModel::compareOrder(const QXmlNodeModelIndex &index, const QXmlNodeModelIndex &otherIndex) const
+{
+ return m_internalModel->compareOrder(index, otherIndex);
+}
+
+QXmlNodeModelIndex XsdValidatedXmlNodeModel::root(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->root(index);
+}
+
+QXmlName XsdValidatedXmlNodeModel::name(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->name(index);
+}
+
+QString XsdValidatedXmlNodeModel::stringValue(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->stringValue(index);
+}
+
+QVariant XsdValidatedXmlNodeModel::typedValue(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->typedValue(index);
+}
+
+QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > XsdValidatedXmlNodeModel::iterate(const QXmlNodeModelIndex &index, QXmlNodeModelIndex::Axis axis) const
+{
+ return m_internalModel->iterate(index, axis);
+}
+
+QPatternist::ItemIteratorPtr XsdValidatedXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->sequencedTypedValue(index);
+}
+
+QPatternist::ItemTypePtr XsdValidatedXmlNodeModel::type(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->type(index);
+}
+
+QXmlName::NamespaceCode XsdValidatedXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &index, const QXmlName::PrefixCode prefix) const
+{
+ return m_internalModel->namespaceForPrefix(index, prefix);
+}
+
+bool XsdValidatedXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &index, const QXmlNodeModelIndex &otherIndex) const
+{
+ return m_internalModel->isDeepEqual(index, otherIndex);
+}
+
+void XsdValidatedXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &index, QAbstractXmlReceiver *const receiver) const
+{
+ m_internalModel->sendNamespaces(index, receiver);
+}
+
+QVector<QXmlName> XsdValidatedXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->namespaceBindings(index);
+}
+
+QXmlNodeModelIndex XsdValidatedXmlNodeModel::elementById(const QXmlName &name) const
+{
+ return m_internalModel->elementById(name);
+}
+
+QVector<QXmlNodeModelIndex> XsdValidatedXmlNodeModel::nodesByIdref(const QXmlName &name) const
+{
+ return m_internalModel->nodesByIdref(name);
+}
+
+void XsdValidatedXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &index, QAbstractXmlReceiver *const receiver, const NodeCopySettings &settings) const
+{
+ return m_internalModel->copyNodeTo(index, receiver, settings);
+}
+
+QXmlNodeModelIndex XsdValidatedXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
+{
+ return m_internalModel->nextFromSimpleAxis(axis, origin);
+}
+
+QVector<QXmlNodeModelIndex> XsdValidatedXmlNodeModel::attributes(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->attributes(index);
+}
+
+void XsdValidatedXmlNodeModel::setAssignedElement(const QXmlNodeModelIndex &index, const XsdElement::Ptr &element)
+{
+ m_assignedElements.insert(index, element);
+}
+
+XsdElement::Ptr XsdValidatedXmlNodeModel::assignedElement(const QXmlNodeModelIndex &index) const
+{
+ if (m_assignedElements.contains(index))
+ return m_assignedElements.value(index);
+ else
+ return XsdElement::Ptr();
+}
+
+void XsdValidatedXmlNodeModel::setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute)
+{
+ m_assignedAttributes.insert(index, attribute);
+}
+
+XsdAttribute::Ptr XsdValidatedXmlNodeModel::assignedAttribute(const QXmlNodeModelIndex &index) const
+{
+ if (m_assignedAttributes.contains(index))
+ return m_assignedAttributes.value(index);
+ else
+ return XsdAttribute::Ptr();
+}
+
+void XsdValidatedXmlNodeModel::setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type)
+{
+ m_assignedTypes.insert(index, type);
+}
+
+SchemaType::Ptr XsdValidatedXmlNodeModel::assignedType(const QXmlNodeModelIndex &index) const
+{
+ if (m_assignedTypes.contains(index))
+ return m_assignedTypes.value(index);
+ else
+ return SchemaType::Ptr();
+}
+
+void XsdValidatedXmlNodeModel::addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)
+{
+ m_idIdRefBindings[id].insert(binding);
+}
+
+QStringList XsdValidatedXmlNodeModel::idIdRefBindingIds() const
+{
+ return m_idIdRefBindings.keys();
+}
+
+QSet<NamedSchemaComponent::Ptr> XsdValidatedXmlNodeModel::idIdRefBindings(const QString &id) const
+{
+ return m_idIdRefBindings.value(id);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h
new file mode 100644
index 0000000..c502835
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdValidatedXmlNodeModel_H
+#define Patternist_XsdValidatedXmlNodeModel_H
+
+#include "qabstractxmlnodemodel.h"
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qitem_p.h"
+#include "qschematype_p.h"
+#include "qxsdelement_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A delegate class that wraps around a QAbstractXmlNodeModel and provides
+ * additional validation specific information.
+ *
+ * This class represents the input XML document enriched with additional type
+ * information that has been assigned during validation.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdValidatedXmlNodeModel : public QAbstractXmlNodeModel
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdValidatedXmlNodeModel> Ptr;
+ typedef QList<Ptr> List;
+
+ /**
+ * Creates a new validated xml node model.
+ */
+ XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model);
+
+ /**
+ * Destroys the validated xml node model.
+ */
+ virtual ~XsdValidatedXmlNodeModel();
+
+ virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const;
+ virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const;
+ virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const;
+ virtual QXmlName name(const QXmlNodeModelIndex &ni) const;
+ virtual QString stringValue(const QXmlNodeModelIndex &n) const;
+ virtual QVariant typedValue(const QXmlNodeModelIndex &n) const;
+ virtual QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > iterate(const QXmlNodeModelIndex &ni, QXmlNodeModelIndex::Axis axis) const;
+ virtual QPatternist::ItemIteratorPtr sequencedTypedValue(const QXmlNodeModelIndex &ni) const;
+ virtual QPatternist::ItemTypePtr type(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlName::NamespaceCode namespaceForPrefix(const QXmlNodeModelIndex &ni, const QXmlName::PrefixCode prefix) const;
+ virtual bool isDeepEqual(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const;
+ virtual void sendNamespaces(const QXmlNodeModelIndex &n, QAbstractXmlReceiver *const receiver) const;
+ virtual QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex &n) const;
+ virtual QXmlNodeModelIndex elementById(const QXmlName &NCName) const;
+ virtual QVector<QXmlNodeModelIndex> nodesByIdref(const QXmlName &NCName) const;
+ virtual void copyNodeTo(const QXmlNodeModelIndex &node, QAbstractXmlReceiver *const receiver, const NodeCopySettings &) const;
+
+ /**
+ * Sets the @p element that is assigned to the xml node at @p index.
+ */
+ void setAssignedElement(const QXmlNodeModelIndex &index, const XsdElement::Ptr &element);
+
+ /**
+ * Returns the element that is assigned to the xml node at @p index.
+ */
+ XsdElement::Ptr assignedElement(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * Sets the @p attribute that is assigned to the xml node at @p index.
+ */
+ void setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Returns the attribute that is assigned to the xml node at @p index.
+ */
+ XsdAttribute::Ptr assignedAttribute(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * Sets the @p type that is assigned to the xml node at @p index.
+ *
+ * @note The type can be a different than the type of the element or
+ * attribute that is assigned to the index, since the instance
+ * document can overwrite it by xsi:type.
+ */
+ void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type);
+
+ /**
+ * Returns the type that is assigned to the xml node at @p index.
+ */
+ SchemaType::Ptr assignedType(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * Adds the attribute or element @p binding with the given @p id.
+ */
+ void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding);
+
+ /**
+ * Returns a list of all binding ids.
+ */
+ QStringList idIdRefBindingIds() const;
+
+ /**
+ * Returns the set of bindings with the given @p id.
+ */
+ QSet<NamedSchemaComponent::Ptr> idIdRefBindings(const QString &id) const;
+
+ protected:
+ virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const;
+ virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex &element) const;
+
+ private:
+ QExplicitlySharedDataPointer<const QAbstractXmlNodeModel> m_internalModel;
+ QHash<QXmlNodeModelIndex, XsdElement::Ptr> m_assignedElements;
+ QHash<QXmlNodeModelIndex, XsdAttribute::Ptr> m_assignedAttributes;
+ QHash<QXmlNodeModelIndex, SchemaType::Ptr> m_assignedTypes;
+ QHash<QString, QSet<NamedSchemaComponent::Ptr> > m_idIdRefBindings;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp
new file mode 100644
index 0000000..622a39f
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp
@@ -0,0 +1,1276 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdvalidatinginstancereader_p.h"
+
+#include "qabstractdatetime_p.h"
+#include "qacceltreeresourceloader_p.h"
+#include "qbase64binary_p.h"
+#include "qboolean_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qderivedinteger_p.h"
+#include "qduration_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qhexbinary_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qpatternplatform_p.h"
+#include "qqnamevalue_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qvaluefactory_p.h"
+#include "qxmlnamepool.h"
+#include "qxmlquery_p.h"
+#include "qxmlschema_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemamerger_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdstatemachinebuilder_p.h"
+#include "qxsdtypechecker_p.h"
+
+#include "qxsdschemadebugger_p.h"
+
+#include <QtCore/QFile>
+#include <QtXmlPatterns/QXmlQuery>
+#include <QtXmlPatterns/QXmlResultItems>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ template <>
+ template <>
+ bool XsdStateMachine<XsdTerm::Ptr>::inputEqualsTransition<QXmlName>(QXmlName name, XsdTerm::Ptr term) const
+ {
+ if (term->isElement()) {
+ return (XsdElement::Ptr(term)->name(m_namePool) == name);
+ } else if (term->isWildcard()) {
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ if (name.namespaceURI() == StandardNamespaces::empty) {
+ name.setNamespaceURI(m_namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+ }
+
+ return XsdSchemaHelper::wildcardAllowsExpandedName(name, XsdWildcard::Ptr(term), m_namePool);
+ }
+
+ return false;
+ }
+}
+
+XsdValidatingInstanceReader::XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context)
+ : XsdInstanceReader(model, context)
+ , m_model(model)
+ , m_namePool(m_context->namePool())
+ , m_xsiNilName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("nil")))
+ , m_xsiTypeName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("type")))
+ , m_xsiSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("schemaLocation")))
+ , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("noNamespaceSchemaLocation")))
+ , m_documentUri(documentUri)
+{
+ m_idRefsType = m_context->schemaTypeFactory()->createSchemaType(m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS")));
+}
+
+void XsdValidatingInstanceReader::addSchema(const XsdSchema::Ptr &schema, const QUrl &locationUrl)
+{
+ if (!m_mergedSchemas.contains(locationUrl)) {
+ m_mergedSchemas.insert(locationUrl, QStringList() << schema->targetNamespace());
+ } else {
+ QStringList &targetNamespaces = m_mergedSchemas[locationUrl];
+ if (targetNamespaces.contains(schema->targetNamespace()))
+ return;
+
+ targetNamespaces.append(schema->targetNamespace());
+ }
+
+ const XsdSchemaMerger merger(m_schema, schema);
+ m_schema = merger.mergedSchema();
+/*
+ XsdSchemaDebugger dbg(m_namePool);
+ dbg.dumpSchema(m_schema);
+*/
+}
+
+bool XsdValidatingInstanceReader::read()
+{
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ return true;
+
+ if (isStartElement()) {
+ const QXmlName elementName = name();
+ const QXmlItem currentItem = item();
+ bool hasStateMachine = false;
+ XsdElement::Ptr processedElement;
+
+ if (!validate(hasStateMachine, processedElement))
+ return false;
+
+ read();
+
+ if (processedElement) { // for wildcard with 'skip' we have no element
+ m_model->setAssignedElement(currentItem.toNodeModelIndex(), processedElement);
+
+ // check identity constraints after all child nodes have been
+ // validated, so that we know there assigned types
+ validateIdentityConstraint(processedElement, currentItem);
+ }
+
+ if (!m_stateMachines.isEmpty() && hasStateMachine) {
+ if (!m_stateMachines.top().inEndState()) {
+ error(QtXmlPatterns::tr("Element %1 is missing child element.").arg(formatKeyword(m_namePool->displayName(elementName))));
+ return false;
+ }
+ m_stateMachines.pop();
+ }
+ }
+ }
+
+ // final validations
+
+ // check IDREF occurrences
+ const QStringList ids = m_model->idIdRefBindingIds();
+ QSetIterator<QString> it(m_idRefs);
+ while (it.hasNext()) {
+ const QString id = it.next();
+ if (!ids.contains(id)) {
+ error(QtXmlPatterns::tr("There is one IDREF value with no corresponding ID: %1.").arg(formatKeyword(id)));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void XsdValidatingInstanceReader::error(const QString &msg) const
+{
+ m_context.data()->error(msg, XsdSchemaContext::XSDError, sourceLocation());
+}
+
+bool XsdValidatingInstanceReader::loadSchema(const QString &targetNamespace, const QUrl &location)
+{
+ const AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(location, m_context->networkAccessManager(),
+ m_context, AccelTreeResourceLoader::ContinueOnError));
+ if (!reply)
+ return true;
+
+ // we have to create a separated schema context here, that however shares the type factory
+ XsdSchemaContext::Ptr context(new XsdSchemaContext(m_namePool));
+ context->m_schemaTypeFactory = m_context->m_schemaTypeFactory;
+
+ QXmlSchemaPrivate schema(context);
+ schema.load(reply.data(), location, targetNamespace);
+ if (!schema.isValid()) {
+ error(QtXmlPatterns::tr("Loaded schema file is invalid."));
+ return false;
+ }
+
+ addSchema(schema.m_schemaParserContext->schema(), location);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validate(bool &hasStateMachine, XsdElement::Ptr &processedElement)
+{
+ // first check if a custom schema is defined
+ if (hasAttribute(m_xsiSchemaLocationName)) {
+ const QString schemaLocation = attribute(m_xsiSchemaLocationName);
+ const QStringList parts = schemaLocation.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ if ((parts.count()%2) == 1) {
+ error(QtXmlPatterns::tr("%1 contains invalid data.").arg(formatKeyword(m_namePool, m_xsiSchemaLocationName)));
+ return false;
+ }
+
+ for (int i = 0; i < parts.count(); i += 2) {
+ const QString identifier = QString::fromLatin1("%1 %2").arg(parts.at(i)).arg(parts.at(i + 1));
+ if (m_processedSchemaLocations.contains(identifier))
+ continue;
+ else
+ m_processedSchemaLocations.insert(identifier);
+
+ // check constraint 4) from http://www.w3.org/TR/xmlschema-1/#schema-loc (only valid for XML Schema 1.0?)
+ if (m_processedNamespaces.contains(parts.at(i))) {
+ error(QtXmlPatterns::tr("xsi:schemaLocation namespace %1 has already appeared earlier in the instance document.").arg(formatKeyword(parts.at(i))));
+ return false;
+ }
+
+ QUrl url(parts.at(i + 1));
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentUri.isValid());
+
+ url = m_documentUri.resolved(url);
+ }
+
+ loadSchema(parts.at(i), url);
+ }
+ }
+
+ if (hasAttribute(m_xsiNoNamespaceSchemaLocationName)) {
+ const QString schemaLocation = attribute(m_xsiNoNamespaceSchemaLocationName);
+
+ if (!m_processedSchemaLocations.contains(schemaLocation)) {
+ m_processedSchemaLocations.insert(schemaLocation);
+
+ if (m_processedNamespaces.contains(QString())) {
+ error(QtXmlPatterns::tr("xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute."));
+ return false;
+ }
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentUri.isValid());
+
+ url = m_documentUri.resolved(url);
+ }
+
+ loadSchema(QString(), url);
+ }
+ }
+
+ m_processedNamespaces.insert(m_namePool->stringForNamespace(name().namespaceURI()));
+
+ if (!m_schema) {
+ error(QtXmlPatterns::tr("No schema defined for validation."));
+ return false;
+ }
+
+ // check if we are 'inside' a type definition
+ if (m_stateMachines.isEmpty()) {
+ // find out the type of the top-level element
+ XsdElement::Ptr element = elementByName(name());
+ if (!element) {
+ if (!hasAttribute(m_xsiTypeName)) {
+ error(QtXmlPatterns::tr("No definition for element %1 available.").arg(formatKeyword(m_namePool, name())));
+ return false;
+ }
+
+ // This instance document has an element with no definition in the schema
+ // but an explicitly given type, that is fine according to the spec.
+ // We will create an element definition manually here and continue the
+ // normal validation process
+ element = XsdElement::Ptr(new XsdElement());
+ element->setName(name());
+ element->setIsAbstract(false);
+ element->setIsNillable(hasAttribute(m_xsiNilName));
+
+ const QString type = qNameAttribute(m_xsiTypeName);
+ const QXmlName typeName = convertToQName(type);
+
+ const SchemaType::Ptr elementType = typeByName(typeName);
+ if (!elementType) {
+ error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
+ return false;
+ }
+ element->setType(elementType);
+ }
+
+ // rememeber the element we process
+ processedElement = element;
+
+ if (!validateElement(element, hasStateMachine)) {
+ return false;
+ }
+
+ } else {
+ if (!m_stateMachines.top().proceed<QXmlName>(name())) {
+ error(QtXmlPatterns::tr("Element %1 is not defined in this scope.").arg(formatKeyword(m_namePool, name())));
+ return false;
+ }
+
+ const XsdTerm::Ptr term = m_stateMachines.top().lastTransition();
+ if (term->isElement()) {
+ const XsdElement::Ptr element(term);
+
+ // rememeber the element we process
+ processedElement = element;
+
+ if (!validateElement(element, hasStateMachine))
+ return false;
+
+ } else {
+ const XsdWildcard::Ptr wildcard(term);
+ if (wildcard->processContents() != XsdWildcard::Skip) {
+ XsdElement::Ptr elementDeclaration = elementByName(name());
+ if (!elementDeclaration) {
+ if (hasAttribute(m_xsiTypeName)) {
+ // This instance document has an element with no definition in the schema
+ // but an explicitly given type, that is fine according to the spec.
+ // We will create an element definition manually here and continue the
+ // normal validation process
+ elementDeclaration = XsdElement::Ptr(new XsdElement());
+ elementDeclaration->setName(name());
+ elementDeclaration->setIsAbstract(false);
+ elementDeclaration->setIsNillable(hasAttribute(m_xsiNilName));
+
+ const QString type = qNameAttribute(m_xsiTypeName);
+ const QXmlName typeName = convertToQName(type);
+
+ const SchemaType::Ptr elementType = typeByName(typeName);
+ if (!elementType) {
+ error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
+ return false;
+ }
+ elementDeclaration->setType(elementType);
+ }
+ }
+
+ if (!elementDeclaration) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Declaration for element %1 does not exist.").arg(formatKeyword(m_namePool->displayName(name()))));
+ return false;
+ } else {
+ // in this case we put a state machine for the xs:anyType on the statemachine stack,
+ // so we accept every content of this element
+
+ createAndPushStateMachine(anyType()->contentType()->particle());
+ hasStateMachine = true;
+ }
+ } else {
+ if (!validateElement(elementDeclaration, hasStateMachine)) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Element %1 contains invalid content.").arg(formatKeyword(m_namePool->displayName(name()))));
+ return false;
+ }
+ }
+
+ // rememeber the type of that element node
+ m_model->setAssignedType(item().toNodeModelIndex(), elementDeclaration->type());
+ }
+ } else { // wildcard process contents type is Skip
+ // in this case we put a state machine for the xs:anyType on the statemachine stack,
+ // so we accept every content of this element
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ wildcard->setProcessContents(XsdWildcard::Skip);
+
+ const XsdParticle::Ptr outerParticle(new XsdParticle());
+ outerParticle->setMinimumOccurs(1);
+ outerParticle->setMaximumOccurs(1);
+
+ const XsdParticle::Ptr innerParticle(new XsdParticle());
+ innerParticle->setMinimumOccurs(0);
+ innerParticle->setMaximumOccursUnbounded(true);
+ innerParticle->setTerm(wildcard);
+
+ const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup());
+ outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+ outerModelGroup->setParticles(XsdParticle::List() << innerParticle);
+ outerParticle->setTerm(outerModelGroup);
+
+ createAndPushStateMachine(outerParticle);
+ hasStateMachine = true;
+ }
+ }
+ }
+
+ return true;
+}
+
+void XsdValidatingInstanceReader::createAndPushStateMachine(const XsdParticle::Ptr &particle)
+{
+ XsdStateMachine<XsdTerm::Ptr> stateMachine(m_namePool);
+
+ XsdStateMachineBuilder builder(&stateMachine, m_namePool, XsdStateMachineBuilder::ValidatingMode);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(particle, endState);
+ builder.addStartState(startState);
+
+/*
+ QString fileName = QString("/tmp/foo_%1.dot").arg(m_namePool->displayName(complexType->name(m_namePool)));
+ QString pngFileName = QString("/tmp/foo_%1.png").arg(m_namePool->displayName(complexType->name(m_namePool)));
+ QFile file(fileName);
+ file.open(QIODevice::WriteOnly);
+ stateMachine.outputGraph(&file, "Hello");
+ file.close();
+ ::system(QString("dot -Tpng %1 -o%2").arg(fileName).arg(pngFileName).toLatin1().data());
+*/
+
+ stateMachine = stateMachine.toDFA();
+
+ m_stateMachines.push(stateMachine);
+}
+
+bool XsdValidatingInstanceReader::validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine)
+{
+ // http://www.w3.org/TR/xmlschema11-1/#d0e10998
+
+ bool isNilled = false;
+
+ // 1 tested already, 'declaration' corresponds D
+
+ // 2
+ if (declaration->isAbstract()) {
+ error(QtXmlPatterns::tr("Element %1 is declared as abstract.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ // 3
+ if (!declaration->isNillable()) {
+ if (hasAttribute(m_xsiNilName)) {
+ error(QtXmlPatterns::tr("Element %1 is not nillable.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false; // 3.1
+ }
+ } else {
+ if (hasAttribute(m_xsiNilName)) {
+ const QString value = attribute(m_xsiNilName);
+ const Boolean::Ptr nil = Boolean::fromLexical(value);
+ if (nil->hasError()) {
+ error(QtXmlPatterns::tr("Attribute %1 contains invalid data: %2").arg(formatKeyword(QLatin1String("nil."))).arg(formatData(value)));
+ return false;
+ }
+
+ // 3.2.3
+ if (nil->as<Boolean>()->value() == true) {
+ // 3.2.3.1
+ if (hasChildElement() || hasChildText()) {
+ error(QtXmlPatterns::tr("Element contains content although it is nillable."));
+ return false;
+ }
+
+ // 3.2.3.2
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ error(QtXmlPatterns::tr("Fixed value constraint not allowed if element is nillable."));
+ return false;
+ }
+ }
+
+ isNilled = nil->as<Boolean>()->value();
+ }
+ }
+
+ SchemaType::Ptr finalElementType = declaration->type();
+
+ // 4
+ if (hasAttribute(m_xsiTypeName)) {
+ const QString type = qNameAttribute(m_xsiTypeName);
+ const QXmlName typeName = convertToQName(type);
+
+ const SchemaType::Ptr elementType = typeByName(typeName);
+ // 4.1
+ if (!elementType) {
+ error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
+ return false;
+ }
+
+ // 4.2
+ SchemaType::DerivationConstraints constraints = 0;
+ if (declaration->disallowedSubstitutions() & NamedSchemaComponent::ExtensionConstraint)
+ constraints |= SchemaType::ExtensionConstraint;
+ if (declaration->disallowedSubstitutions() & NamedSchemaComponent::RestrictionConstraint)
+ constraints |= SchemaType::RestrictionConstraint;
+
+ if (!XsdSchemaHelper::isValidlySubstitutable(elementType, declaration->type(), constraints)) {
+ if (declaration->type()->name(m_namePool) != BuiltinTypes::xsAnyType->name(m_namePool)) { // xs:anyType is a valid substitutable type here
+ error(QtXmlPatterns::tr("Specified type %1 is not validly substitutable with element type %2.").arg(formatType(m_namePool, elementType)).arg(formatType(m_namePool, declaration->type())));
+ return false;
+ }
+ }
+
+ finalElementType = elementType;
+ }
+
+ if (!validateElementType(declaration, finalElementType, isNilled, hasStateMachine))
+ return false;
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749
+
+ // 1 checked already
+
+ // 2
+ if (type->isComplexType() && type->isDefinedBySchema()) {
+ if (XsdComplexType::Ptr(type)->isAbstract()) {
+ error(QtXmlPatterns::tr("Complex type %1 is not allowed to be abstract.").arg(formatType(m_namePool, type)));
+ return false;
+ }
+ }
+
+ // 3
+ if (type->isSimpleType())
+ return validateElementSimpleType(declaration, type, isNilled); // 3.1
+ else
+ return validateElementComplexType(declaration, type, isNilled, hasStateMachine); // 3.2
+}
+
+bool XsdValidatingInstanceReader::validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749
+
+ // 3.1.1
+ const QSet<QXmlName> allowedAttributes(QSet<QXmlName>() << m_xsiNilName << m_xsiTypeName << m_xsiSchemaLocationName << m_xsiNoNamespaceSchemaLocationName);
+ QSet<QXmlName> elementAttributes = attributeNames();
+ elementAttributes.subtract(allowedAttributes);
+ if (!elementAttributes.isEmpty()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed attributes.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ // 3.1.2
+ if (hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed child element.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ // 3.1.3
+ if (!isNilled) {
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context);
+
+ QString actualValue;
+ if (hasChildText()) {
+ actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+ } else {
+ if (declaration->valueConstraint())
+ actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ }
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+
+ const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation());
+ if (!checker.isValidString(actualValue, type, errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // additional check
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ if (!text().isEmpty() && !checker.valuesAreEqual(actualValue, actualConstraintValue, type)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+
+ // 4 checked in validateElement already
+
+ // rememeber the type of that element node
+ m_model->setAssignedType(item().toNodeModelIndex(), type);
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context);
+ const QString actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(type)) {
+ addIdIdRefBinding(actualValue, declaration);
+ }
+
+ if (m_idRefsType->wxsTypeMatches(type)) {
+ const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < idRefs.count(); ++i) {
+ m_idRefs.insert(idRefs.at(i));
+ }
+ } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(type)) {
+ m_idRefs.insert(actualValue);
+ }
+
+ return true;
+}
+
+static bool hasIDAttributeUse(const XsdAttributeUse::List &uses)
+{
+ const int count = uses.count();
+ for (int i = 0; i < count; ++i) {
+ if (BuiltinTypes::xsID->wxsTypeMatches(uses.at(i)->attribute()->type()))
+ return true;
+ }
+
+ return false;
+}
+
+bool XsdValidatingInstanceReader::validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-complex-type
+
+ // 1
+ if (!isNilled) {
+ XsdComplexType::Ptr complexType;
+
+ if (type->isDefinedBySchema()) {
+ complexType = XsdComplexType::Ptr(type);
+ } else {
+ if (type->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool))
+ complexType = anyType();
+ }
+
+ if (complexType) {
+ // 1.1
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ if (hasChildText() || hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed child content.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ // 1.2
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed child element.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context);
+ QString actualValue;
+ if (hasChildText()) {
+ actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+ } else {
+ if (declaration->valueConstraint())
+ actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ }
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+ const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation());
+ if (!checker.isValidString(actualValue, complexType->contentType()->simpleType(), errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // additional check
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ if (!checker.valuesAreEqual(actualValue, declaration->valueConstraint()->value(), boundType)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+
+ // 1.3
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) {
+ if (!text().simplified().isEmpty()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed text content.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ // 1.4
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+
+ if (complexType->contentType()->particle()) {
+ createAndPushStateMachine(complexType->contentType()->particle());
+ hasStateMachine = true;
+ }
+
+ // additional check
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ if (hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 cannot contain other elements, as it has a fixed content.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context);
+ QString actualValue;
+ if (hasChildText()) {
+ actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+ } else {
+ if (declaration->valueConstraint())
+ actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ }
+
+ if (actualValue != declaration->valueConstraint()->value()) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(type);
+
+ // create a lookup hash for faster access
+ QHash<QXmlName, XsdAttributeUse::Ptr> attributeUseHash;
+ {
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+ for (int i = 0; i < attributeUses.count(); ++i)
+ attributeUseHash.insert(attributeUses.at(i)->attribute()->name(m_namePool), attributeUses.at(i));
+ }
+
+ const QSet<QXmlName> attributes(attributeNames());
+
+ // 3
+ QHashIterator<QXmlName, XsdAttributeUse::Ptr> usesIt(attributeUseHash);
+ while (usesIt.hasNext()) {
+ usesIt.next();
+
+ if (usesIt.value()->isRequired()) {
+ if (!attributes.contains(usesIt.key())) {
+ error(QtXmlPatterns::tr("Element %1 is missing required attribute %2.").arg(formatKeyword(declaration->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool->displayName(usesIt.key()))));
+ return false;
+ }
+ }
+ }
+
+ bool hasIDAttribute = hasIDAttributeUse(complexType->attributeUses());
+
+ // 2
+ QSetIterator<QXmlName> it(attributes);
+ while (it.hasNext()) {
+ const QXmlName attributeName = it.next();
+
+ // skip builtin attributes
+ if (attributeName == m_xsiNilName ||
+ attributeName == m_xsiTypeName ||
+ attributeName == m_xsiSchemaLocationName ||
+ attributeName == m_xsiNoNamespaceSchemaLocationName)
+ continue;
+
+ // 2.1
+ if (attributeUseHash.contains(attributeName) && (attributeUseHash.value(attributeName)->useType() != XsdAttributeUse::ProhibitedUse)) {
+ if (!validateAttribute(attributeUseHash.value(attributeName), attribute(attributeName)))
+ return false;
+ } else { // 2.2
+ if (complexType->attributeWildcard()) {
+ const XsdWildcard::Ptr wildcard(complexType->attributeWildcard());
+ if (!validateAttributeWildcard(attributeName, wildcard)) {
+ error(QtXmlPatterns::tr("Attribute %1 does not match the attribute wildcard.").arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+
+ if (wildcard->processContents() != XsdWildcard::Skip) {
+ const XsdAttribute::Ptr attributeDeclaration = attributeByName(attributeName);
+
+ if (!attributeDeclaration) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Declaration for attribute %1 does not exist.").arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+ } else {
+ if (BuiltinTypes::xsID->wxsTypeMatches(attributeDeclaration->type())) {
+ if (hasIDAttribute) {
+ error(QtXmlPatterns::tr("Element %1 contains two attributes of type %2.")
+ .arg(formatKeyword(declaration->displayName(m_namePool)))
+ .arg(formatKeyword("ID")));
+ return false;
+ }
+
+ hasIDAttribute = true;
+ }
+
+ if (!validateAttribute(attributeDeclaration, attribute(attributeName))) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Attribute %1 contains invalid content.").arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+ }
+ }
+ }
+ } else {
+ error(QtXmlPatterns::tr("Element %1 contains unknown attribute %2.").arg(formatKeyword(declaration->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+ }
+ }
+ }
+
+ // 4
+ // so what?...
+
+ // 5
+ // hmm...
+
+ // 6
+ // TODO: check assertions
+
+ // 7
+ // TODO: check type table restrictions
+
+ // rememeber the type of that element node
+ m_model->setAssignedType(item().toNodeModelIndex(), type);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value)
+{
+ const AnySimpleType::Ptr attributeType = declaration->attribute()->type();
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context);
+
+ const QString actualValue = XsdTypeChecker::normalizedValue(value, facets);
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+
+ const QXmlNodeModelIndex index = attributeItem(declaration->attribute()->name(m_namePool)).toNodeModelIndex();
+
+ const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation());
+ if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match its type definition: %2.").arg(formatKeyword(declaration->attribute()->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
+ const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match defined value constraint.").arg(formatKeyword(declaration->attribute()->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(declaration->attribute()->type())) {
+ addIdIdRefBinding(actualValue, declaration->attribute());
+ }
+
+ if (m_idRefsType->wxsTypeMatches(declaration->attribute()->type())) {
+ const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < idRefs.count(); ++i)
+ m_idRefs.insert(idRefs.at(i));
+ } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->attribute()->type())) {
+ m_idRefs.insert(actualValue);
+ }
+
+ m_model->setAssignedType(index, declaration->attribute()->type());
+ m_model->setAssignedAttribute(index, declaration->attribute());
+
+ return true;
+}
+
+//TODO: merge that with the method above
+bool XsdValidatingInstanceReader::validateAttribute(const XsdAttribute::Ptr &declaration, const QString &value)
+{
+ const AnySimpleType::Ptr attributeType = declaration->type();
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context);
+
+ const QString actualValue = XsdTypeChecker::normalizedValue(value, facets);
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+
+ const QXmlNodeModelIndex index = attributeItem(declaration->name(m_namePool)).toNodeModelIndex();
+
+ const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation());
+ if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) {
+ const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(declaration->type())) {
+ addIdIdRefBinding(actualValue, declaration);
+ }
+
+ if (m_idRefsType->wxsTypeMatches(declaration->type())) {
+ const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < idRefs.count(); ++i)
+ m_idRefs.insert(idRefs.at(i));
+ } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->type())) {
+ m_idRefs.insert(actualValue);
+ }
+
+ m_model->setAssignedType(index, declaration->type());
+ m_model->setAssignedAttribute(index, declaration);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name(attributeName);
+ if (name.namespaceURI() == StandardNamespaces::empty) {
+ name.setNamespaceURI(m_namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+ }
+
+ return XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, m_namePool);
+}
+
+bool XsdValidatingInstanceReader::validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem &currentItem)
+{
+ const XsdIdentityConstraint::List constraints = element->identityConstraints();
+
+ for (int i = 0; i < constraints.count(); ++i) {
+ const XsdIdentityConstraint::Ptr constraint = constraints.at(i);
+
+ TargetNode::Set targetNodeSet, qualifiedNodeSet;
+ selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet);
+
+ if (constraint->category() == XsdIdentityConstraint::Unique) {
+ if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet))
+ return false;
+ } else if (constraint->category() == XsdIdentityConstraint::Key) {
+ if (!validateKeyIdentityConstraint(element, constraint, targetNodeSet, qualifiedNodeSet))
+ return false;
+ }
+ }
+
+ // we do the keyref check in a separated run to make sure that all keys are available
+ for (int i = 0; i < constraints.count(); ++i) {
+ const XsdIdentityConstraint::Ptr constraint = constraints.at(i);
+ if (constraint->category() == XsdIdentityConstraint::KeyReference) {
+ TargetNode::Set targetNodeSet, qualifiedNodeSet;
+ selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet);
+
+ if (!validateKeyRefIdentityConstraint(element, constraint, qualifiedNodeSet))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateUniqueIdentityConstraint(const XsdElement::Ptr&, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
+
+ // 4.1
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation());
+
+ QSetIterator<TargetNode> it(qualifiedNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+ QSetIterator<TargetNode> innerIt(qualifiedNodeSet);
+ while (innerIt.hasNext()) {
+ const TargetNode innerNode = innerIt.next();
+
+ if (node == innerNode) // do not compare with ourself
+ continue;
+
+ if (node.fieldsAreEqual(innerNode, m_namePool, m_context, &reflection)) {
+ error(QtXmlPatterns::tr("Non-unique value found for constraint %1.").arg(formatKeyword(constraint->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+
+ m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
+
+ // 4.2
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation());
+
+ // 4.2.1
+ if (targetNodeSet.count() != qualifiedNodeSet.count()) {
+ error(QtXmlPatterns::tr("Key constraint %1 contains absent fields.").arg(formatKeyword(constraint->displayName(m_namePool))));
+ return false;
+ }
+
+ // 4.2.2
+ if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet))
+ return false;
+
+ // 4.2.3
+ QSetIterator<TargetNode> it(qualifiedNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+ const QVector<QXmlItem> fieldItems = node.fieldItems();
+ for (int i = 0; i < fieldItems.count(); ++i) {
+ const QXmlNodeModelIndex index = fieldItems.at(i).toNodeModelIndex();
+ if (m_model->kind(index) == QXmlNodeModelIndex::Element) {
+ const XsdElement::Ptr declaration = m_model->assignedElement(index);
+ if (declaration && declaration->isNillable()) {
+ error(QtXmlPatterns::tr("Key constraint %1 contains references nillable element %2.")
+ .arg(formatKeyword(constraint->displayName(m_namePool)))
+ .arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+ }
+
+ m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateKeyRefIdentityConstraint(const XsdElement::Ptr&, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
+
+ // 4.3
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation());
+
+ const TargetNode::Set keySet = m_idcKeys.value(constraint->referencedKey()->name(m_namePool));
+
+ QSetIterator<TargetNode> it(qualifiedNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+
+ bool foundMatching = false;
+
+ QSetIterator<TargetNode> keyIt(keySet);
+ while (keyIt.hasNext()) {
+ const TargetNode keyNode = keyIt.next();
+
+ if (node.fieldsAreEqual(keyNode, m_namePool, m_context, &reflection)) {
+ foundMatching = true;
+ break;
+ }
+ }
+
+ if (!foundMatching) {
+ error(QtXmlPatterns::tr("No referenced value found for key reference %1.").arg(formatKeyword(constraint->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QXmlQuery XsdValidatingInstanceReader::createXQuery(const QList<QXmlName> &namespaceBindings, const QXmlItem &contextNode, const QString &queryString) const
+{
+ // create a public name pool from our name pool
+ QXmlNamePool namePool(m_namePool.data());
+
+ // the QXmlQuery shall work with the same name pool as we do
+ QXmlQuery query(namePool);
+
+ // add additional namespace bindings
+ QXmlQueryPrivate *queryPrivate = query.d;
+
+ for (int i = 0; i < namespaceBindings.count(); ++i) {
+ if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
+ queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i));
+ }
+
+ // set the context node for that query and the query string
+ query.setFocus(contextNode);
+ query.setQuery(queryString, m_documentUri);
+
+ return query;
+}
+
+bool XsdValidatingInstanceReader::selectNodeSets(const XsdElement::Ptr&, const QXmlItem &currentItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet)
+{
+ // at first select all target nodes
+ const XsdXPathExpression::Ptr selector = constraint->selector();
+ const XsdXPathExpression::List fields = constraint->fields();
+
+ QXmlQuery query = createXQuery(selector->namespaceBindings(), currentItem, selector->expression());
+
+ QXmlResultItems resultItems;
+ query.evaluateTo(&resultItems);
+
+ // now we iterate over all target nodes and select the fields for each node
+ QXmlItem item(resultItems.next());
+ while (!item.isNull()) {
+
+ TargetNode targetNode(item);
+
+ for (int i = 0; i < fields.count(); ++i) {
+ const XsdXPathExpression::Ptr field = fields.at(i);
+ QXmlQuery fieldQuery = createXQuery(field->namespaceBindings(), item, field->expression());
+
+ QXmlResultItems fieldResultItems;
+ fieldQuery.evaluateTo(&fieldResultItems);
+
+ // copy result into vetor for better testing...
+ QVector<QXmlItem> fieldVector;
+ QXmlItem fieldItem(fieldResultItems.next());
+ while (!fieldItem.isNull()) {
+ fieldVector.append(fieldItem);
+ fieldItem = fieldResultItems.next();
+ }
+
+ if (fieldVector.count() > 1) {
+ error(QtXmlPatterns::tr("More than one value found for field %1.").arg(formatData(field->expression())));
+ return false;
+ }
+
+ if (fieldVector.count() == 1) {
+ fieldItem = fieldVector.first();
+
+ const QXmlNodeModelIndex index = fieldItem.toNodeModelIndex();
+ const SchemaType::Ptr type = m_model->assignedType(index);
+
+ bool typeOk = true;
+ if (type->isComplexType()) {
+ if (type->isDefinedBySchema()) {
+ if (XsdComplexType::Ptr(type)->contentType()->variety() != XsdComplexType::ContentType::Simple)
+ typeOk = false;
+ } else {
+ typeOk = false;
+ }
+ }
+ if (!typeOk) {
+ error(QtXmlPatterns::tr("Field %1 has no simple type.").arg(formatData(field->expression())));
+ return false;
+ }
+
+ SchemaType::Ptr targetType = type;
+ QString value = m_model->stringValue(fieldItem.toNodeModelIndex());
+
+ if (type->isDefinedBySchema()) {
+ if (type->isSimpleType())
+ targetType = XsdSimpleType::Ptr(type)->primitiveType();
+ else
+ targetType = XsdComplexType::Ptr(type)->contentType()->simpleType();
+ } else {
+ if (BuiltinTypes::xsAnySimpleType->name(m_namePool) == type->name(m_namePool)) {
+ targetType = BuiltinTypes::xsString;
+ value = QLatin1String("___anySimpleType_value");
+ }
+ }
+
+ // if it is xs:QName derived type, we normalize the name content
+ // and do a string comparison
+ if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ targetType = BuiltinTypes::xsString;
+
+ const QXmlName qName = convertToQName(value.trimmed());
+ value = QString::fromLatin1("%1:%2").arg(m_namePool->stringForNamespace(qName.namespaceURI())).arg(m_namePool->stringForLocalName(qName.localName()));
+ }
+
+ targetNode.addField(fieldItem, value, targetType);
+ } else {
+ // we add an empty entry here, that makes comparison easier later on
+ targetNode.addField(QXmlItem(), QString(), SchemaType::Ptr());
+ }
+ }
+
+ targetNodeSet.insert(targetNode);
+
+ item = resultItems.next();
+ }
+
+ // copy all items from target node set to qualified node set, that have no empty fields
+ QSetIterator<TargetNode> it(targetNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+ if (node.emptyFieldsCount() == 0)
+ qualifiedNodeSet.insert(node);
+ }
+
+ return true;
+}
+
+XsdElement::Ptr XsdValidatingInstanceReader::elementByName(const QXmlName &name) const
+{
+ return m_schema->element(name);
+}
+
+XsdAttribute::Ptr XsdValidatingInstanceReader::attributeByName(const QXmlName &name) const
+{
+ return m_schema->attribute(name);
+}
+
+SchemaType::Ptr XsdValidatingInstanceReader::typeByName(const QXmlName &name) const
+{
+ const SchemaType::Ptr type = m_schema->type(name);
+ if (type)
+ return type;
+
+ return m_context->schemaTypeFactory()->createSchemaType(name);
+}
+
+void XsdValidatingInstanceReader::addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)
+{
+ if (!m_model->idIdRefBindings(id).isEmpty()) {
+ error(QtXmlPatterns::tr("ID value '%1' is not unique.").arg(formatKeyword(id)));
+ return;
+ }
+
+ m_model->addIdIdRefBinding(id, binding);
+}
+
+QString XsdValidatingInstanceReader::qNameAttribute(const QXmlName &attributeName)
+{
+ const QString value = attribute(attributeName).simplified();
+ if (!XPathHelper::isQName(value)) {
+ error(QtXmlPatterns::tr("'%1' attribute contains invalid QName content: %2.").arg(m_namePool->displayName(attributeName)).arg(formatData(value)));
+ return QString();
+ } else {
+ return value;
+ }
+}
+
+XsdComplexType::Ptr XsdValidatingInstanceReader::anyType()
+{
+ if (m_anyType)
+ return m_anyType;
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ wildcard->setProcessContents(XsdWildcard::Lax);
+
+ const XsdParticle::Ptr outerParticle(new XsdParticle());
+ outerParticle->setMinimumOccurs(1);
+ outerParticle->setMaximumOccurs(1);
+
+ const XsdParticle::Ptr innerParticle(new XsdParticle());
+ innerParticle->setMinimumOccurs(0);
+ innerParticle->setMaximumOccursUnbounded(true);
+ innerParticle->setTerm(wildcard);
+
+ const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup());
+ outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+ outerModelGroup->setParticles(XsdParticle::List() << innerParticle);
+ outerParticle->setTerm(outerModelGroup);
+
+ m_anyType = XsdComplexType::Ptr(new XsdComplexType());
+ m_anyType->setName(BuiltinTypes::xsAnyType->name(m_namePool));
+ m_anyType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ m_anyType->contentType()->setVariety(XsdComplexType::ContentType::Mixed);
+ m_anyType->contentType()->setParticle(outerParticle);
+ m_anyType->setAttributeWildcard(wildcard);
+ m_anyType->setIsAbstract(false);
+
+ return m_anyType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h
new file mode 100644
index 0000000..4dc736a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdValidatingInstanceReader_H
+#define Patternist_XsdValidatingInstanceReader_H
+
+#include "qxsdidchelper_p.h"
+#include "qxsdinstancereader_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdvalidatedxmlnodemodel_p.h"
+
+#include <QtCore/QStack>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlQuery;
+
+namespace QPatternist
+{
+ /**
+ * @short The validating schema instance reader.
+ *
+ * This class reads in a xml instance document from a QAbstractXmlNodeModel and
+ * validates it against a given xml schema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdValidatingInstanceReader : public XsdInstanceReader
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdValidatingInstanceReader> Ptr;
+
+ /**
+ * Creates a new validating instance reader that reads the data from
+ * the given @p model.
+ *
+ * @param model The model the data shall be read from.
+ * @param documentUri The uri of the document the model is from.
+ * @param context The context that is used to report errors etc.
+ */
+ XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context);
+
+ /**
+ * Adds a new @p schema to the pool of schemas that shall be used
+ * for validation.
+ * The schema is located at the given @p url.
+ */
+ void addSchema(const XsdSchema::Ptr &schema, const QUrl &url);
+
+ /**
+ * Reads and validates the instance document.
+ */
+ bool read();
+
+ private:
+ /**
+ * Loads a schema with the given @p targetNamespace from the given @p location
+ * and adds it to the pool of schemas that are used for validation.
+ *
+ * This method is used to load schemas defined in the xsi:schemaLocation or
+ * xsi:noNamespaceSchemaLocation attributes in the instance document.
+ */
+ bool loadSchema(const QString &targetNamespace, const QUrl &location);
+
+ /**
+ * Reports an error via the report context.
+ */
+ void error(const QString &msg) const;
+
+ /**
+ * Validates the current element tag of the instance document.
+ *
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ * @param element Used to remember which element has been validated in this step.
+ */
+ bool validate(bool &hasStateMachine, XsdElement::Ptr &element);
+
+ /**
+ * Validates the current tag of the instance document against the given element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ */
+ bool validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine);
+
+ /**
+ * Validates the current tag of the instance document against the given @p type of the element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param type The type to validate against.
+ * @param isNilled Defines whether the element is nilled by the instance document.
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ *
+ * @note The @p type can differ from the element @p declaration type if the instance document has defined
+ * it via xsi:type attribute.
+ */
+ bool validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine);
+
+ /**
+ * Validates the current tag of the instance document against the given simple @p type of the element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param type The type to validate against.
+ * @param isNilled Defines whether the element is nilled by the instance document.
+ *
+ * @note The @p type can differ from the element @p declaration type if the instance document has defined
+ * it via xsi:type attribute.
+ */
+ bool validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled);
+
+ /**
+ * Validates the current tag of the instance document against the given complex @p type of the element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param type The type to validate against.
+ * @param isNilled Defines whether the element is nilled by the instance document.
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ *
+ * @note The @p type can differ from the element @p declaration type if the instance document has defined
+ * it via xsi:type attribute.
+ */
+ bool validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine);
+
+ /**
+ * Validates the given @p value against the attribute use @p declaration.
+ */
+ bool validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value);
+
+ /**
+ * Validates the given @p value against the attribute @p declaration.
+ */
+ bool validateAttribute(const XsdAttribute::Ptr &declaration, const QString &value);
+
+ /**
+ * Validates the given @p attributeName against the @p wildcard.
+ */
+ bool validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Validates the identity constraints of an @p element.
+ */
+ bool validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem &currentItem);
+
+ /**
+ * Validates the <em>unique</em> identity @p constraint of the @p element.
+ */
+ bool validateUniqueIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Validates the <em>key</em> identity @p constraint of the @p element.
+ */
+ bool validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Validates the <em>keyref</em> identity @p constraint of the @p element.
+ */
+ bool validateKeyRefIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Selects two sets of nodes that match the given identity @p constraint.
+ *
+ * @param element The element the identity constraint belongs to.
+ * @param currentItem The current element that will be used as focus for the XQuery.
+ * @param constraint The constraint (selector and fields) that describe the two sets.
+ * @param targetNodeSet The target node set as defined by the schema specification.
+ * @param qualifiedNodeSet The qualified node set as defined by the schema specification.
+ */
+ bool selectNodeSets(const XsdElement::Ptr &element, const QXmlItem &currentItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Creates an QXmlQuery object with the defined @p namespaceBindings that has the @p contextNode as focus
+ * and will execute @p query.
+ */
+ QXmlQuery createXQuery(const QList<QXmlName> &namespaceBindings, const QXmlItem &contextNode, const QString &query) const;
+
+ /**
+ * Returns the element declaration with the given @p name from the pool of all schemas.
+ */
+ XsdElement::Ptr elementByName(const QXmlName &name) const;
+
+ /**
+ * Returns the attribute declaration with the given @p name from the pool of all schemas.
+ */
+ XsdAttribute::Ptr attributeByName(const QXmlName &name) const;
+
+ /**
+ * Returns the type declaration with the given @p name from the pool of all schemas.
+ */
+ SchemaType::Ptr typeByName(const QXmlName &name) const;
+
+ /**
+ * Adds the ID/IDREF binding to the validated model and checks for duplicates.
+ */
+ void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding);
+
+ /**
+ * Helper method that reads an attribute of type xs:QName and does
+ * syntax checking.
+ */
+ QString qNameAttribute(const QXmlName &attributeName);
+
+ /**
+ * Returns the xs:anyType that is used to build up the state machine.
+ * We need that as the BuiltinTypes::xsAnyType is not a XsdComplexType.
+ */
+ XsdComplexType::Ptr anyType();
+
+ /**
+ * Helper method that creates a state machine for the given @p particle
+ * and pushes it on the state machine stack.
+ */
+ void createAndPushStateMachine(const XsdParticle::Ptr &particle);
+
+ typedef QHash<QUrl, QStringList> MergedSchemas;
+ typedef QHashIterator<QUrl, QStringList> MergedSchemasIterator;
+
+ XsdValidatedXmlNodeModel::Ptr m_model;
+ MergedSchemas m_mergedSchemas;
+ XsdSchema::Ptr m_schema;
+ const NamePool::Ptr m_namePool;
+ const QXmlName m_xsiNilName;
+ const QXmlName m_xsiTypeName;
+ const QXmlName m_xsiSchemaLocationName;
+ const QXmlName m_xsiNoNamespaceSchemaLocationName;
+
+ QStack<XsdStateMachine<XsdTerm::Ptr> > m_stateMachines;
+ QUrl m_documentUri;
+ XsdComplexType::Ptr m_anyType;
+ QSet<QString> m_processedNamespaces;
+ QSet<QString> m_processedSchemaLocations;
+ QSet<QString> m_idRefs;
+ QHash<QXmlName, TargetNode::Set> m_idcKeys;
+ SchemaType::Ptr m_idRefsType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdwildcard.cpp b/src/xmlpatterns/schema/qxsdwildcard.cpp
new file mode 100644
index 0000000..abf490e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdwildcard.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdwildcard_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QString XsdWildcard::absentNamespace()
+{
+ return QLatin1String("__ns_absent");
+}
+
+void XsdWildcard::NamespaceConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdWildcard::NamespaceConstraint::Variety XsdWildcard::NamespaceConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdWildcard::NamespaceConstraint::setNamespaces(const QSet<QString> &namespaces)
+{
+ m_namespaces = namespaces;
+}
+
+QSet<QString> XsdWildcard::NamespaceConstraint::namespaces() const
+{
+ return m_namespaces;
+}
+
+void XsdWildcard::NamespaceConstraint::setDisallowedNames(const QSet<QString> &names)
+{
+ m_disallowedNames = names;
+}
+
+QSet<QString> XsdWildcard::NamespaceConstraint::disallowedNames() const
+{
+ return m_disallowedNames;
+}
+
+XsdWildcard::XsdWildcard()
+ : m_namespaceConstraint(new NamespaceConstraint())
+ , m_processContents(Strict)
+{
+ m_namespaceConstraint->setVariety(NamespaceConstraint::Any);
+}
+
+bool XsdWildcard::isWildcard() const
+{
+ return true;
+}
+
+void XsdWildcard::setNamespaceConstraint(const NamespaceConstraint::Ptr &namespaceConstraint)
+{
+ m_namespaceConstraint = namespaceConstraint;
+}
+
+XsdWildcard::NamespaceConstraint::Ptr XsdWildcard::namespaceConstraint() const
+{
+ return m_namespaceConstraint;
+}
+
+void XsdWildcard::setProcessContents(ProcessContents contents)
+{
+ m_processContents = contents;
+}
+
+XsdWildcard::ProcessContents XsdWildcard::processContents() const
+{
+ return m_processContents;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdwildcard_p.h b/src/xmlpatterns/schema/qxsdwildcard_p.h
new file mode 100644
index 0000000..8940f13
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdwildcard_p.h
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdWildcard_H
+#define Patternist_XsdWildcard_H
+
+#include "qxsdterm_p.h"
+
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD wildcard object.
+ *
+ * This class represents the <em>wildcard</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#Wildcards">here</a>.
+ *
+ * It contains information from either an <em>any</em> object or an <em>anyAttribute</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSWildcard">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdWildcard : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdWildcard> Ptr;
+
+ /**
+ * Defines the absent namespace that is used in wildcards.
+ */
+ static QString absentNamespace();
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#w-namespace_constraint">namespace constraint</a> of the wildcard.
+ */
+ class NamespaceConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NamespaceConstraint> Ptr;
+
+ /**
+ * Describes the variety of the namespace constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nc-variety">Variety Definition</a>
+ */
+ enum Variety
+ {
+ Any, ///< Any namespace is allowed.
+ Enumeration, ///< Namespaces in the namespaces set are allowed.
+ Not ///< Namespaces in the namespaces set are not allowed.
+ };
+
+ /**
+ * Sets the @p variety of the namespace constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nc-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the namespace constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the set of @p namespaces of the namespace constraint.
+ */
+ void setNamespaces(const QSet<QString> &namespaces);
+
+ /**
+ * Returns the set of namespaces of the namespace constraint.
+ */
+ QSet<QString> namespaces() const;
+
+ /**
+ * Sets the set of disallowed @p names of the namespace constraint.
+ */
+ void setDisallowedNames(const QSet<QString> &names);
+
+ /**
+ * Returns the set of disallowed names of the namespace constraint.
+ */
+ QSet<QString> disallowedNames() const;
+
+ private:
+ Variety m_variety;
+ QSet<QString> m_namespaces;
+ QSet<QString> m_disallowedNames;
+ };
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#w-process_contents">type of content processing</a> of the wildcard.
+ */
+ enum ProcessContents
+ {
+ Strict, ///< There must be a top-level declaration for the item available, or the item must have an xsi:type, and the item must be valid as appropriate.
+ Lax, ///< If the item has a uniquely determined declaration available, it must be valid with respect to that definition.
+ Skip ///< No constraints at all: the item must simply be well-formed XML.
+ };
+
+ /**
+ * Creates a new wildcard object.
+ */
+ XsdWildcard();
+
+ /**
+ * Returns always @c true, used to avoid dynamic casts.
+ */
+ virtual bool isWildcard() const;
+
+ /**
+ * Sets the namespace @p constraint of the wildcard.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#w-namespace_constraint">Namespace Constraint Definition</a>
+ */
+ void setNamespaceConstraint(const NamespaceConstraint::Ptr &constraint);
+
+ /**
+ * Returns the namespace constraint of the wildcard.
+ */
+ NamespaceConstraint::Ptr namespaceConstraint() const;
+
+ /**
+ * Sets the process @p contents of the wildcard.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#w-process_contents">Process Contents Definition</a>
+ */
+ void setProcessContents(ProcessContents contents);
+
+ /**
+ * Returns the process contents of the wildcard.
+ */
+ ProcessContents processContents() const;
+
+ private:
+ NamespaceConstraint::Ptr m_namespaceConstraint;
+ ProcessContents m_processContents;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdxpathexpression.cpp b/src/xmlpatterns/schema/qxsdxpathexpression.cpp
new file mode 100644
index 0000000..d5b4f1a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdxpathexpression.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdxpathexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdXPathExpression::setNamespaceBindings(const QList<QXmlName> &set)
+{
+ m_namespaceBindings = set;
+}
+
+QList<QXmlName> XsdXPathExpression::namespaceBindings() const
+{
+ return m_namespaceBindings;
+}
+
+void XsdXPathExpression::setDefaultNamespace(const AnyURI::Ptr &defaultNs)
+{
+ m_defaultNamespace = defaultNs;
+}
+
+AnyURI::Ptr XsdXPathExpression::defaultNamespace() const
+{
+ return m_defaultNamespace;
+}
+
+void XsdXPathExpression::setBaseURI(const AnyURI::Ptr &uri)
+{
+ m_baseURI = uri;
+}
+
+AnyURI::Ptr XsdXPathExpression::baseURI() const
+{
+ return m_baseURI;
+}
+
+void XsdXPathExpression::setExpression(const QString &expression)
+{
+ m_expression = expression;
+}
+
+QString XsdXPathExpression::expression() const
+{
+ return m_expression;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdxpathexpression_p.h b/src/xmlpatterns/schema/qxsdxpathexpression_p.h
new file mode 100644
index 0000000..8685da5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdxpathexpression_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XsdXPathExpression_H
+#define Patternist_XsdXPathExpression_H
+
+#include "qanyuri_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD assertion object.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x">XPathExpression Definition</a>
+ */
+ class XsdXPathExpression : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdXPathExpression> Ptr;
+ typedef QList<XsdXPathExpression::Ptr> List;
+
+ /**
+ * Sets the list of namespace @p bindings of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-namespace_bindings">Namespace Bindings Definition</a>
+ *
+ * @note We can't use a QSet<QXmlName> here, as the hash method does not take the prefix
+ * in account, so we loose entries.
+ */
+ void setNamespaceBindings(const QList<QXmlName> &bindings);
+
+ /**
+ * Returns the list of namespace bindings of the XPath expression.
+ */
+ QList<QXmlName> namespaceBindings() const;
+
+ /**
+ * Sets the default namespace of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-default_namespace">Default Namespace Definition</a>
+ */
+ void setDefaultNamespace(const AnyURI::Ptr &defaultNamespace);
+
+ /**
+ * Returns the default namespace of the XPath expression.
+ */
+ AnyURI::Ptr defaultNamespace() const;
+
+ /**
+ * Sets the base @p uri of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-base_URI">Base URI Definition</a>
+ */
+ void setBaseURI(const AnyURI::Ptr &uri);
+
+ /**
+ * Returns the base uri of the XPath expression.
+ */
+ AnyURI::Ptr baseURI() const;
+
+ /**
+ * Sets the @p expression string of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-expression">Expression Definition</a>
+ */
+ void setExpression(const QString &expression);
+
+ /**
+ * Returns the expression string of the XPath expression.
+ */
+ QString expression() const;
+
+ private:
+ QList<QXmlName> m_namespaceBindings;
+ AnyURI::Ptr m_defaultNamespace;
+ AnyURI::Ptr m_baseURI;
+ QString m_expression;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/schema.pri b/src/xmlpatterns/schema/schema.pri
new file mode 100644
index 0000000..b00d64b
--- /dev/null
+++ b/src/xmlpatterns/schema/schema.pri
@@ -0,0 +1,93 @@
+HEADERS += $$PWD/qnamespacesupport_p.h \
+ $$PWD/qxsdalternative_p.h \
+ $$PWD/qxsdannotated_p.h \
+ $$PWD/qxsdannotation_p.h \
+ $$PWD/qxsdapplicationinformation_p.h \
+ $$PWD/qxsdassertion_p.h \
+ $$PWD/qxsdattribute_p.h \
+ $$PWD/qxsdattributereference_p.h \
+ $$PWD/qxsdattributeterm_p.h \
+ $$PWD/qxsdattributeuse_p.h \
+ $$PWD/qxsdattributegroup_p.h \
+ $$PWD/qxsdcomplextype_p.h \
+ $$PWD/qxsddocumentation_p.h \
+ $$PWD/qxsdelement_p.h \
+ $$PWD/qxsdfacet_p.h \
+ $$PWD/qxsdidcache_p.h \
+ $$PWD/qxsdidchelper_p.h \
+ $$PWD/qxsdidentityconstraint_p.h \
+ $$PWD/qxsdinstancereader_p.h \
+ $$PWD/qxsdmodelgroup_p.h \
+ $$PWD/qxsdnotation_p.h \
+ $$PWD/qxsdparticle_p.h \
+ $$PWD/qxsdparticlechecker_p.h \
+ $$PWD/qxsdreference_p.h \
+ $$PWD/qxsdsimpletype_p.h \
+ $$PWD/qxsdschema_p.h \
+ $$PWD/qxsdschemachecker_p.h \
+ $$PWD/qxsdschemacontext_p.h \
+ $$PWD/qxsdschemadebugger_p.h \
+ $$PWD/qxsdschemahelper_p.h \
+ $$PWD/qxsdschemamerger_p.h \
+ $$PWD/qxsdschemaparser_p.h \
+ $$PWD/qxsdschemaparsercontext_p.h \
+ $$PWD/qxsdschemaresolver_p.h \
+ $$PWD/qxsdschematoken_p.h \
+ $$PWD/qxsdschematypesfactory_p.h \
+ $$PWD/qxsdstatemachine_p.h \
+ $$PWD/qxsdstatemachinebuilder_p.h \
+ $$PWD/qxsdterm_p.h \
+ $$PWD/qxsdtypechecker_p.h \
+ $$PWD/qxsduserschematype_p.h \
+ $$PWD/qxsdvalidatedxmlnodemodel_p.h \
+ $$PWD/qxsdvalidatinginstancereader_p.h \
+ $$PWD/qxsdwildcard_p.h \
+ $$PWD/qxsdxpathexpression_p.h
+
+SOURCES += $$PWD/qnamespacesupport.cpp \
+ $$PWD/qxsdalternative.cpp \
+ $$PWD/qxsdannotated.cpp \
+ $$PWD/qxsdannotation.cpp \
+ $$PWD/qxsdapplicationinformation.cpp \
+ $$PWD/qxsdassertion.cpp \
+ $$PWD/qxsdattribute.cpp \
+ $$PWD/qxsdattributereference.cpp \
+ $$PWD/qxsdattributeterm.cpp \
+ $$PWD/qxsdattributeuse.cpp \
+ $$PWD/qxsdattributegroup.cpp \
+ $$PWD/qxsdcomplextype.cpp \
+ $$PWD/qxsddocumentation.cpp \
+ $$PWD/qxsdelement.cpp \
+ $$PWD/qxsdfacet.cpp \
+ $$PWD/qxsdidcache.cpp \
+ $$PWD/qxsdidchelper.cpp \
+ $$PWD/qxsdidentityconstraint.cpp \
+ $$PWD/qxsdinstancereader.cpp \
+ $$PWD/qxsdmodelgroup.cpp \
+ $$PWD/qxsdnotation.cpp \
+ $$PWD/qxsdparticle.cpp \
+ $$PWD/qxsdparticlechecker.cpp \
+ $$PWD/qxsdreference.cpp \
+ $$PWD/qxsdsimpletype.cpp \
+ $$PWD/qxsdschema.cpp \
+ $$PWD/qxsdschemachecker.cpp \
+ $$PWD/qxsdschemachecker_setup.cpp \
+ $$PWD/qxsdschemacontext.cpp \
+ $$PWD/qxsdschemadebugger.cpp \
+ $$PWD/qxsdschemahelper.cpp \
+ $$PWD/qxsdschemamerger.cpp \
+ $$PWD/qxsdschemaparser.cpp \
+ $$PWD/qxsdschemaparser_setup.cpp \
+ $$PWD/qxsdschemaparsercontext.cpp \
+ $$PWD/qxsdschemaresolver.cpp \
+ $$PWD/qxsdschematoken.cpp \
+ $$PWD/qxsdschematypesfactory.cpp \
+ $$PWD/qxsdstatemachinebuilder.cpp \
+ $$PWD/qxsdterm.cpp \
+ $$PWD/qxsdtypechecker.cpp \
+ $$PWD/qxsdwildcard.cpp \
+ $$PWD/qxsdvalidatedxmlnodemodel.cpp \
+ $$PWD/qxsdvalidatinginstancereader.cpp \
+ $$PWD/qxsdxpathexpression.cpp
+
+RESOURCES += $$PWD/builtinschemas.qrc
diff --git a/src/xmlpatterns/schema/schemas/xml.xsd b/src/xmlpatterns/schema/schemas/xml.xsd
new file mode 100644
index 0000000..eeb9db5
--- /dev/null
+++ b/src/xmlpatterns/schema/schemas/xml.xsd
@@ -0,0 +1,145 @@
+<?xml version='1.0'?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:annotation>
+ <xs:documentation>
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ id (as an attribute name): denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+ attributes on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ &lt;schema . . .>
+ . . .
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ &lt;type . . .>
+ . . .
+ &lt;attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2007/08/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself, or with the XML namespace itself. In other words, if the XML
+ Schema or XML namespaces change, the version of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2007/08/xml.xsd will not change.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+ <xs:annotation>
+ <xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility. See
+ RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+ at http://www.iana.org/assignments/lang-tag-apps.htm for
+ further information.
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.</xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:union memberTypes="xs:language">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value=""/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="id" type="xs:ID">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xml-id/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+</xs:schema>
diff --git a/src/xmlpatterns/schema/schemas/xml.xsd-LICENSE b/src/xmlpatterns/schema/schemas/xml.xsd-LICENSE
new file mode 100644
index 0000000..2c687d8
--- /dev/null
+++ b/src/xmlpatterns/schema/schemas/xml.xsd-LICENSE
@@ -0,0 +1,40 @@
+W3C® SOFTWARE NOTICE AND LICENSE
+
+This license came from: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This work (and included software, documentation such as READMEs, or other
+related items) is being provided by the copyright holders under the following
+license. By obtaining, using and/or copying this work, you (the licensee)
+agree that you have read, understood, and will comply with the following
+terms and conditions.
+
+Permission to copy, modify, and distribute this software and its
+documentation, with or without modification, for any purpose and without
+fee or royalty is hereby granted, provided that you include the following on
+ALL copies of the software and documentation or portions thereof, including
+modifications:
+
+ 1. The full text of this NOTICE in a location viewable to users of the
+ redistributed or derivative work.
+ 2. Any pre-existing intellectual property disclaimers, notices, or terms
+ and conditions. If none exist, the W3C Software Short Notice should be
+ included (hypertext is preferred, text is permitted)
+ within the body of any redistributed or derivative code.
+ 3. Notice of any changes or modifications to the files, including the date
+ changes were made. (We recommend you provide URIs to the location from
+ which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS
+MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
+PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
+ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in
+advertising or publicity pertaining to the software without specific, written
+prior permission. Title to copyright in this software and any associated
+documentation will at all times remain with copyright holders.
diff --git a/src/xmlpatterns/schema/tokens.xml b/src/xmlpatterns/schema/tokens.xml
new file mode 100644
index 0000000..b3b8e18
--- /dev/null
+++ b/src/xmlpatterns/schema/tokens.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tokenAutomaton scope="public"
+ className="XsdSchemaToken"
+ headerFile="qxsdschematoken_p.h"
+ sourceFile="qxsdschematoken.cpp"
+ defaultToken="NoKeyword"
+ tokenEnum="NodeName"
+ hasToString="true"
+ includeGuardName="QPatternist_XsdSchemaToken_h">
+ <tokens>
+ <token>abstract</token>
+ <token>all</token>
+ <token>alternative</token>
+ <token>annotation</token>
+ <token>any</token>
+ <token>anyAttribute</token>
+ <token>appinfo</token>
+ <token>appliesToEmpty</token>
+ <token>assert</token>
+ <token>assertion</token>
+ <token>attribute</token>
+ <token>attributeFormDefault</token>
+ <token>attributeGroup</token>
+ <token>base</token>
+ <token>block</token>
+ <token>blockDefault</token>
+ <token>choice</token>
+ <token>collapse</token>
+ <token>complexContent</token>
+ <token>complexType</token>
+ <token>default</token>
+ <token>defaultAttributes</token>
+ <token>defaultAttributesApply</token>
+ <token>defaultOpenContent</token>
+ <token>documentation</token>
+ <token>element</token>
+ <token>elementFormDefault</token>
+ <token>enumeration</token>
+ <token>extension</token>
+ <token>field</token>
+ <token>final</token>
+ <token>finalDefault</token>
+ <token>fixed</token>
+ <token>form</token>
+ <token>fractionDigits</token>
+ <token>group</token>
+ <token>id</token>
+ <token>import</token>
+ <token>include</token>
+ <token>itemType</token>
+ <token>key</token>
+ <token>keyref</token>
+ <token>length</token>
+ <token>list</token>
+ <token>maxExclusive</token>
+ <token>maxInclusive</token>
+ <token>maxLength</token>
+ <token>maxOccurs</token>
+ <token>memberTypes</token>
+ <token>minExclusive</token>
+ <token>minInclusive</token>
+ <token>minLength</token>
+ <token>minOccurs</token>
+ <token>mixed</token>
+ <token>mode</token>
+ <token>name</token>
+ <token>namespace</token>
+ <token>nillable</token>
+ <token>notation</token>
+ <token>notNamespace</token>
+ <token>notQName</token>
+ <token>openContent</token>
+ <token>override</token>
+ <token>preserve</token>
+ <token>pattern</token>
+ <token>processContents</token>
+ <token>public</token>
+ <token>redefine</token>
+ <token>ref</token>
+ <token>refer</token>
+ <token>replace</token>
+ <token>restriction</token>
+ <token>schema</token>
+ <token>schemaLocation</token>
+ <token>selector</token>
+ <token>sequence</token>
+ <token>simpleContent</token>
+ <token>simpleType</token>
+ <token>source</token>
+ <token>substitutionGroup</token>
+ <token>system</token>
+ <token>targetNamespace</token>
+ <token>test</token>
+ <token>totalDigits</token>
+ <token>type</token>
+ <token>union</token>
+ <token>unique</token>
+ <token>use</token>
+ <token>value</token>
+ <token>version</token>
+ <token>whiteSpace</token>
+ <token>xpath</token>
+ <token name="XPathDefaultNamespace">xpathDefaultNamespace</token>
+ <token name="XmlLanguage">xml:lang</token>
+ <token name="XML_NS_SCHEMA_URI">http://www.w3.org/2001/XMLSchema</token>
+ </tokens>
+
+ <boilerplate>
+
+ <prolog>/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+</prolog>
+
+ </boilerplate>
+
+</tokenAutomaton>
diff --git a/src/xmlpatterns/type/qabstractnodetest.cpp b/src/xmlpatterns/type/qabstractnodetest.cpp
new file mode 100644
index 0000000..63a4fa0
--- /dev/null
+++ b/src/xmlpatterns/type/qabstractnodetest.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractnodetest_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AbstractNodeTest::AbstractNodeTest(const ItemType::Ptr &primaryType) : m_primaryType(primaryType)
+{
+ Q_ASSERT(m_primaryType);
+}
+
+bool AbstractNodeTest::xdtTypeMatches(const ItemType::Ptr &other) const
+{
+ Q_ASSERT(other);
+
+ if(other->isNodeType())
+ {
+ if(*other == *this)
+ return true;
+ else
+ return xdtTypeMatches(other->xdtSuperType());
+ }
+ else
+ return false;
+}
+
+ItemType::Ptr AbstractNodeTest::atomizedType() const
+{
+ return m_primaryType->atomizedType();
+}
+
+ItemType::Ptr AbstractNodeTest::xdtSuperType() const
+{
+ return m_primaryType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qabstractnodetest_p.h b/src/xmlpatterns/type/qabstractnodetest_p.h
new file mode 100644
index 0000000..f219644
--- /dev/null
+++ b/src/xmlpatterns/type/qabstractnodetest_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AbstractNodeTest_H
+#define Patternist_AbstractNodeTest_H
+
+#include "qanynodetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A name test that is of the type <tt>prefix:ncName</tt>.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AbstractNodeTest : public AnyNodeType
+ {
+ public:
+ AbstractNodeTest(const ItemType::Ptr &primaryType);
+
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+ virtual ItemType::Ptr xdtSuperType() const;
+ virtual ItemType::Ptr atomizedType() const;
+
+ protected:
+ const ItemType::Ptr m_primaryType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qanyitemtype.cpp b/src/xmlpatterns/type/qanyitemtype.cpp
new file mode 100644
index 0000000..47bc6d8
--- /dev/null
+++ b/src/xmlpatterns/type/qanyitemtype.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+
+#include "qanyitemtype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AnyItemType::AnyItemType()
+{
+}
+
+bool AnyItemType::itemMatches(const Item &) const
+{
+ return true;
+}
+
+bool AnyItemType::xdtTypeMatches(const ItemType::Ptr &) const
+{
+ return true;
+}
+
+QString AnyItemType::displayName(const NamePool::Ptr &) const
+{
+ return QLatin1String("item()");
+}
+
+ItemType::Ptr AnyItemType::xdtSuperType() const
+{
+ return ItemType::Ptr();
+}
+
+bool AnyItemType::isNodeType() const
+{
+ return false;
+}
+
+bool AnyItemType::isAtomicType() const
+{
+ return false;
+}
+
+ItemType::Ptr AnyItemType::atomizedType() const
+{
+ return BuiltinTypes::xsAnyAtomicType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qanyitemtype_p.h b/src/xmlpatterns/type/qanyitemtype_p.h
new file mode 100644
index 0000000..c62c168
--- /dev/null
+++ b/src/xmlpatterns/type/qanyitemtype_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AnyItemType_H
+#define Patternist_AnyItemType_H
+
+#include "qatomictype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents the <tt>item()</tt> item type.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AnyItemType : public ItemType
+ {
+ public:
+ /**
+ * @returns always "item()"
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * @returns always @c true
+ */
+ virtual bool itemMatches(const Item &item) const;
+
+ /**
+ * @returns always 0, item() is the super type in the
+ * XPath Data Model hierarchy
+ */
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isNodeType() const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isAtomicType() const;
+
+ /**
+ * @returns always @c true
+ */
+ virtual bool xdtTypeMatches(const ItemType::Ptr &type) const;
+
+ /**
+ * @returns xs:anyAtomicType
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ protected:
+ friend class BuiltinTypes;
+ AnyItemType();
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qanynodetype.cpp b/src/xmlpatterns/type/qanynodetype.cpp
new file mode 100644
index 0000000..eac45cf
--- /dev/null
+++ b/src/xmlpatterns/type/qanynodetype.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+
+#include "qanynodetype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool AnyNodeType::xdtTypeMatches(const ItemType::Ptr &other) const
+{
+ return other->isNodeType();
+}
+
+bool AnyNodeType::itemMatches(const Item &item) const
+{
+ return item.isNode();
+}
+
+ItemType::Ptr AnyNodeType::atomizedType() const
+{
+ return BuiltinTypes::xsAnyAtomicType;
+}
+
+QString AnyNodeType::displayName(const NamePool::Ptr &) const
+{
+ return QLatin1String("node()");
+}
+
+ItemType::Ptr AnyNodeType::xdtSuperType() const
+{
+ return BuiltinTypes::item;
+}
+
+bool AnyNodeType::isNodeType() const
+{
+ return true;
+}
+
+bool AnyNodeType::isAtomicType() const
+{
+ return false;
+}
+
+QXmlNodeModelIndex::NodeKind AnyNodeType::nodeKind() const
+{
+ /* node() is an abstract type, so we don't have a value for it in
+ * QXmlNodeModelIndex::NodeKind. */
+ return QXmlNodeModelIndex::NodeKind(0);
+}
+
+PatternPriority AnyNodeType::patternPriority() const
+{
+ return -0.5;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qanynodetype_p.h b/src/xmlpatterns/type/qanynodetype_p.h
new file mode 100644
index 0000000..d502b51
--- /dev/null
+++ b/src/xmlpatterns/type/qanynodetype_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AnyNodeType_H
+#define Patternist_AnyNodeType_H
+
+#include "qatomictype_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents the <tt>node()</tt> item type.
+ *
+ * @ingroup Patternist_types
+ * @see BuiltinNodeType
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AnyNodeType : public ItemType
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<AnyNodeType> Ptr;
+
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+ virtual bool itemMatches(const Item &item) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ virtual bool isNodeType() const;
+ virtual bool isAtomicType() const;
+
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/#acc-summ-typed-value">XQuery 1.0
+ * and XPath 2.0 Data Model, G.15 dm:typed-value Accessor</a>
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ /**
+ * @returns the node kind this node ItemType tests for. If it matches any node, zero is returned.
+ */
+ virtual QXmlNodeModelIndex::NodeKind nodeKind() const;
+
+ virtual PatternPriority patternPriority() const;
+
+ protected:
+ friend class BuiltinTypes;
+
+ inline AnyNodeType()
+ {
+ }
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qanysimpletype.cpp b/src/xmlpatterns/type/qanysimpletype.cpp
new file mode 100644
index 0000000..7ebb2d3
--- /dev/null
+++ b/src/xmlpatterns/type/qanysimpletype.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qanysimpletype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AnySimpleType::AnySimpleType()
+{
+}
+
+AnySimpleType::~AnySimpleType()
+{
+}
+
+QXmlName AnySimpleType::name(const NamePool::Ptr &np) const
+{
+ return np->allocateQName(StandardNamespaces::xs, QLatin1String("anySimpleType"));
+}
+
+QString AnySimpleType::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(name(np));
+}
+
+SchemaType::Ptr AnySimpleType::wxsSuperType() const
+{
+ return BuiltinTypes::xsAnyType;
+}
+
+SchemaType::TypeCategory AnySimpleType::category() const
+{
+ return None;
+}
+
+SchemaType::DerivationMethod AnySimpleType::derivationMethod() const
+{
+ return DerivationRestriction;
+}
+
+bool AnySimpleType::isSimpleType() const
+{
+ return true;
+}
+
+bool AnySimpleType::isComplexType() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qanysimpletype_p.h b/src/xmlpatterns/type/qanysimpletype_p.h
new file mode 100644
index 0000000..5391ad0
--- /dev/null
+++ b/src/xmlpatterns/type/qanysimpletype_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AnySimpleType_H
+#define Patternist_AnySimpleType_H
+
+#include "qanytype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class AtomicType;
+
+ /**
+ * @short Represents the @c xs:anySimpleType item type.
+ *
+ * @ingroup Patternist_types
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#dt-anySimpleType">XML Schema Part 2:
+ * Datatypes Second Edition, The simple ur-type definition</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AnySimpleType : public AnyType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AnySimpleType> Ptr;
+ typedef QList<AnySimpleType::Ptr> List;
+ friend class BuiltinTypes;
+
+ virtual ~AnySimpleType();
+
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+
+ /**
+ * @returns always @c xs:anySimpleType
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * @returns always BuiltinTypes::xsAnyType
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * xs:anySimpleType is the special "simple ur-type". Therefore this function
+ * returns SchemaType::None
+ *
+ * @returns SchemaType::None
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * The simple ur-type is a "special restriction of the ur-type definition",
+ * according to XML Schema Part 2: Datatypes Second Edition about xs:anySimpleType
+ *
+ * @returns DERIVATION_RESTRICTION
+ */
+ virtual SchemaType::DerivationMethod derivationMethod() const;
+
+ /**
+ * Always returns @c true.
+ */
+ virtual bool isSimpleType() const;
+
+ /**
+ * Always returns @c false.
+ */
+ virtual bool isComplexType() const;
+
+ protected:
+ AnySimpleType();
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qanytype.cpp b/src/xmlpatterns/type/qanytype.cpp
new file mode 100644
index 0000000..626f4b4
--- /dev/null
+++ b/src/xmlpatterns/type/qanytype.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+
+#include "qanytype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AnyType::~AnyType()
+{
+}
+
+bool AnyType::wxsTypeMatches(const SchemaType::Ptr &other) const
+{
+ if(other)
+ return this == other.data() ? true : wxsTypeMatches(other->wxsSuperType());
+ else
+ return false;
+}
+
+bool AnyType::isAbstract() const
+{
+ return false;
+}
+
+QXmlName AnyType::name(const NamePool::Ptr &np) const
+{
+ return np->allocateQName(StandardNamespaces::xs, QLatin1String("anyType"));
+}
+
+QString AnyType::displayName(const NamePool::Ptr &) const
+{
+ /* A bit faster than calling name()->displayName() */
+ return QLatin1String("xs:anyType");
+}
+
+SchemaType::Ptr AnyType::wxsSuperType() const
+{
+ return SchemaType::Ptr();
+}
+
+SchemaType::TypeCategory AnyType::category() const
+{
+ return None;
+}
+
+bool AnyType::isComplexType() const
+{
+ return true;
+}
+
+SchemaType::DerivationMethod AnyType::derivationMethod() const
+{
+ return NoDerivation;
+}
+
+SchemaType::DerivationConstraints AnyType::derivationConstraints() const
+{
+ return SchemaType::DerivationConstraints();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qanytype_p.h b/src/xmlpatterns/type/qanytype_p.h
new file mode 100644
index 0000000..0e1ff38
--- /dev/null
+++ b/src/xmlpatterns/type/qanytype_p.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AnyType_H
+#define Patternist_AnyType_H
+
+#include "qschematype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class AtomicType;
+
+ /**
+ * @short Represents the @c xs:anyType item type.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AnyType : public SchemaType
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<AnyType> Ptr;
+ friend class BuiltinTypes;
+
+ virtual ~AnyType();
+
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+
+ /**
+ * @returns always "xs:anyType"
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isAbstract() const;
+
+ /**
+ * @returns @c null, since <tt>xs:anyType</tt> has no base type, it is the ur-type.
+ *
+ * @returns always @c null
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * @returns @c true only if @p other is xsAnyType.
+ */
+ virtual bool wxsTypeMatches(const SchemaType::Ptr &other) const;
+
+ /**
+ * <tt>xs:anyType</tt> is the "ur-type" and special. Therefore, this function
+ * returns SchemaType::None.
+ *
+ * @returns SchemaType::None
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * @returns always NoDerivation.
+ */
+ virtual DerivationMethod derivationMethod() const;
+
+ /**
+ * @returns an empty set of derivation constraint flags.
+ */
+ virtual DerivationConstraints derivationConstraints() const;
+
+ /**
+ * Always returns @c true.
+ */
+ virtual bool isComplexType() const;
+
+ protected:
+ /**
+ * @short This constructor is protected, because this
+ * class must be sub-classed.
+ */
+ inline AnyType()
+ {
+ }
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomiccasterlocator.cpp b/src/xmlpatterns/type/qatomiccasterlocator.cpp
new file mode 100644
index 0000000..f77f200
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocator.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomiccasterlocator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+#define implCasterVisit(type) \
+AtomicTypeVisitorResult::Ptr AtomicCasterLocator::visit(const type *, \
+ const SourceLocationReflection *const) const \
+{ \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+
+implCasterVisit(AnyAtomicType)
+implCasterVisit(AnyURIType)
+implCasterVisit(Base64BinaryType)
+implCasterVisit(BooleanType)
+implCasterVisit(DateTimeType)
+implCasterVisit(DateType)
+implCasterVisit(DayTimeDurationType)
+implCasterVisit(DecimalType)
+implCasterVisit(DoubleType)
+implCasterVisit(DurationType)
+implCasterVisit(FloatType)
+implCasterVisit(GDayType)
+implCasterVisit(GMonthDayType)
+implCasterVisit(GMonthType)
+implCasterVisit(GYearMonthType)
+implCasterVisit(GYearType)
+implCasterVisit(HexBinaryType)
+implCasterVisit(IntegerType)
+implCasterVisit(NOTATIONType)
+implCasterVisit(QNameType)
+implCasterVisit(StringType)
+implCasterVisit(SchemaTimeType)
+implCasterVisit(UntypedAtomicType)
+implCasterVisit(YearMonthDurationType)
+
+#undef implCasterVisit
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qatomiccasterlocator_p.h b/src/xmlpatterns/type/qatomiccasterlocator_p.h
new file mode 100644
index 0000000..0a12b94
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocator_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicCasterLocator_H
+#define Patternist_AtomicCasterLocator_H
+
+#include "qatomictypedispatch_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicCasterLocator : public AtomicTypeVisitor
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AtomicCasterLocator> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyAtomicType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const NOTATIONType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const SourceLocationReflection *const reflection) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomiccasterlocators.cpp b/src/xmlpatterns/type/qatomiccasterlocators.cpp
new file mode 100644
index 0000000..2004421
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocators.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloatcasters_p.h"
+
+#include "qatomiccasterlocators_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+#define impl(owner, mather, type) \
+AtomicTypeVisitorResult::Ptr owner::visit(const type *, \
+ const SourceLocationReflection *const) const \
+{ \
+ return AtomicTypeVisitorResult::Ptr(new mather()); \
+}
+
+#define implSelf(owner) impl(To##owner##CasterLocator, SelfToSelfCaster, owner##Type)
+
+/* xs:string */
+implSelf(String)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, AnyURIType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, Base64BinaryType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, BooleanType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, DateTimeType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, DateType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, DayTimeDurationType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, DecimalType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, DoubleType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, DurationType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, FloatType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, GDayType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, GMonthDayType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, GMonthType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, GYearMonthType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, GYearType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, HexBinaryType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, IntegerType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, NOTATIONType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, QNameType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, SchemaTimeType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, UntypedAtomicType)
+impl(ToStringCasterLocator, ToStringCaster<TypeString>, YearMonthDurationType)
+
+/* xs:untypedAtomic */
+implSelf(UntypedAtomic)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, AnyURIType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, Base64BinaryType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, BooleanType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, DateTimeType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, DateType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, DayTimeDurationType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, DecimalType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, DoubleType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, DurationType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, FloatType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, GDayType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, GMonthDayType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, GMonthType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, GYearMonthType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, GYearType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, HexBinaryType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, IntegerType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, NOTATIONType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, QNameType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, StringType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, SchemaTimeType)
+impl(ToUntypedAtomicCasterLocator, ToUntypedAtomicCaster, YearMonthDurationType)
+
+/* xs:anyURI */
+implSelf(AnyURI)
+impl(ToAnyURICasterLocator, ToAnyURICaster, StringType)
+impl(ToAnyURICasterLocator, ToAnyURICaster, UntypedAtomicType)
+
+/* xs:boolean */
+implSelf(Boolean)
+impl(ToBooleanCasterLocator, NumericToBooleanCaster, DoubleType)
+impl(ToBooleanCasterLocator, NumericToBooleanCaster, FloatType)
+impl(ToBooleanCasterLocator, NumericToBooleanCaster, DecimalType)
+impl(ToBooleanCasterLocator, NumericToBooleanCaster, IntegerType)
+impl(ToBooleanCasterLocator, StringToBooleanCaster, StringType)
+impl(ToBooleanCasterLocator, StringToBooleanCaster, UntypedAtomicType)
+
+/* xs:double */
+implSelf(Double)
+impl(ToDoubleCasterLocator, BooleanToDoubleCaster, BooleanType)
+impl(ToDoubleCasterLocator, NumericToDoubleCaster, FloatType)
+impl(ToDoubleCasterLocator, NumericToDoubleCaster, DecimalType)
+impl(ToDoubleCasterLocator, NumericToDoubleCaster, IntegerType)
+impl(ToDoubleCasterLocator, StringToDoubleCaster, StringType)
+impl(ToDoubleCasterLocator, StringToDoubleCaster, UntypedAtomicType)
+
+/* xs:float */
+implSelf(Float)
+impl(ToFloatCasterLocator, BooleanToFloatCaster, BooleanType)
+impl(ToFloatCasterLocator, NumericToFloatCaster, DoubleType)
+impl(ToFloatCasterLocator, NumericToFloatCaster, DecimalType)
+impl(ToFloatCasterLocator, NumericToFloatCaster, IntegerType)
+impl(ToFloatCasterLocator, StringToFloatCaster, StringType)
+impl(ToFloatCasterLocator, StringToFloatCaster, UntypedAtomicType)
+
+/* xs:decimal */
+implSelf(Decimal)
+impl(ToDecimalCasterLocator, BooleanToDecimalCaster, BooleanType)
+impl(ToDecimalCasterLocator, NumericToDecimalCaster<false>, DoubleType)
+impl(ToDecimalCasterLocator, NumericToDecimalCaster<false>, FloatType)
+impl(ToDecimalCasterLocator, NumericToDecimalCaster<false>, IntegerType)
+impl(ToDecimalCasterLocator, StringToDecimalCaster, StringType)
+impl(ToDecimalCasterLocator, StringToDecimalCaster, UntypedAtomicType)
+
+/* xs:integer */
+implSelf(Integer)
+impl(ToIntegerCasterLocator, BooleanToIntegerCaster, BooleanType)
+impl(ToIntegerCasterLocator, NumericToDecimalCaster<true>, DoubleType)
+impl(ToIntegerCasterLocator, NumericToDecimalCaster<true>, FloatType)
+impl(ToIntegerCasterLocator, NumericToDecimalCaster<true>, DecimalType)
+impl(ToIntegerCasterLocator, StringToIntegerCaster, StringType)
+impl(ToIntegerCasterLocator, StringToIntegerCaster, UntypedAtomicType)
+
+/* xs:base64binary */
+implSelf(Base64Binary)
+impl(ToBase64BinaryCasterLocator, HexBinaryToBase64BinaryCaster, HexBinaryType)
+impl(ToBase64BinaryCasterLocator, StringToBase64BinaryCaster, StringType)
+impl(ToBase64BinaryCasterLocator, StringToBase64BinaryCaster, UntypedAtomicType)
+
+/* xs:hexBinary */
+implSelf(HexBinary)
+impl(ToHexBinaryCasterLocator, Base64BinaryToHexBinaryCaster, Base64BinaryType)
+impl(ToHexBinaryCasterLocator, StringToHexBinaryCaster, StringType)
+impl(ToHexBinaryCasterLocator, StringToHexBinaryCaster, UntypedAtomicType)
+
+/* xs:QName */
+implSelf(QName)
+impl(ToQNameCasterLocator, ToStringCaster<TypeString>, StringType)
+
+/* xs:gYear */
+implSelf(GYear)
+impl(ToGYearCasterLocator, StringToGYearCaster, StringType)
+impl(ToGYearCasterLocator, StringToGYearCaster, UntypedAtomicType)
+impl(ToGYearCasterLocator, AbstractDateTimeToGYearCaster, DateType)
+impl(ToGYearCasterLocator, AbstractDateTimeToGYearCaster, DateTimeType)
+
+/* xs:gDay */
+implSelf(GDay)
+impl(ToGDayCasterLocator, StringToGDayCaster, StringType)
+impl(ToGDayCasterLocator, StringToGDayCaster, UntypedAtomicType)
+impl(ToGDayCasterLocator, AbstractDateTimeToGDayCaster, DateType)
+impl(ToGDayCasterLocator, AbstractDateTimeToGDayCaster, DateTimeType)
+
+/* xs:gMonth */
+implSelf(GMonth)
+impl(ToGMonthCasterLocator, StringToGMonthCaster, StringType)
+impl(ToGMonthCasterLocator, StringToGMonthCaster, UntypedAtomicType)
+impl(ToGMonthCasterLocator, AbstractDateTimeToGMonthCaster, DateType)
+impl(ToGMonthCasterLocator, AbstractDateTimeToGMonthCaster, DateTimeType)
+
+/* xs:gYearMonth */
+implSelf(GYearMonth)
+impl(ToGYearMonthCasterLocator, StringToGYearMonthCaster, StringType)
+impl(ToGYearMonthCasterLocator, StringToGYearMonthCaster, UntypedAtomicType)
+impl(ToGYearMonthCasterLocator, AbstractDateTimeToGYearMonthCaster, DateType)
+impl(ToGYearMonthCasterLocator, AbstractDateTimeToGYearMonthCaster, DateTimeType)
+
+/* xs:gMonthDay */
+implSelf(GMonthDay)
+impl(ToGMonthDayCasterLocator, StringToGMonthDayCaster, StringType)
+impl(ToGMonthDayCasterLocator, StringToGMonthDayCaster, UntypedAtomicType)
+impl(ToGMonthDayCasterLocator, AbstractDateTimeToGMonthDayCaster, DateType)
+impl(ToGMonthDayCasterLocator, AbstractDateTimeToGMonthDayCaster, DateTimeType)
+
+/* xs:dateTime */
+implSelf(DateTime)
+impl(ToDateTimeCasterLocator, StringToDateTimeCaster, StringType)
+impl(ToDateTimeCasterLocator, AbstractDateTimeToDateTimeCaster, DateType)
+impl(ToDateTimeCasterLocator, StringToDateTimeCaster, UntypedAtomicType)
+
+/* xs:time */
+implSelf(SchemaTime)
+impl(ToSchemaTimeCasterLocator, StringToTimeCaster, StringType)
+impl(ToSchemaTimeCasterLocator, AbstractDateTimeToTimeCaster, DateTimeType)
+impl(ToSchemaTimeCasterLocator, StringToTimeCaster, UntypedAtomicType)
+
+/* xs:date */
+implSelf(Date)
+impl(ToDateCasterLocator, StringToDateCaster, StringType)
+impl(ToDateCasterLocator, AbstractDateTimeToDateCaster, DateTimeType)
+impl(ToDateCasterLocator, StringToDateCaster, UntypedAtomicType)
+
+/* xs:duration */
+implSelf(Duration)
+impl(ToDurationCasterLocator, AbstractDurationToDurationCaster, DayTimeDurationType)
+impl(ToDurationCasterLocator, AbstractDurationToDurationCaster, YearMonthDurationType)
+impl(ToDurationCasterLocator, StringToDurationCaster, StringType)
+impl(ToDurationCasterLocator, StringToDurationCaster, UntypedAtomicType)
+
+/* xs:dayTimeDuration */
+implSelf(DayTimeDuration)
+impl(ToDayTimeDurationCasterLocator, AbstractDurationToDayTimeDurationCaster, DurationType)
+impl(ToDayTimeDurationCasterLocator, AbstractDurationToDayTimeDurationCaster, YearMonthDurationType)
+impl(ToDayTimeDurationCasterLocator, StringToDayTimeDurationCaster, StringType)
+impl(ToDayTimeDurationCasterLocator, StringToDayTimeDurationCaster, UntypedAtomicType)
+
+/* xs:yearMonthDuration */
+implSelf(YearMonthDuration)
+impl(ToYearMonthDurationCasterLocator, AbstractDurationToYearMonthDurationCaster, DayTimeDurationType)
+impl(ToYearMonthDurationCasterLocator, AbstractDurationToYearMonthDurationCaster, DurationType)
+impl(ToYearMonthDurationCasterLocator, StringToYearMonthDurationCaster, StringType)
+impl(ToYearMonthDurationCasterLocator, StringToYearMonthDurationCaster, UntypedAtomicType)
+
+#undef implSelf
+#undef impl
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qatomiccasterlocators_p.h b/src/xmlpatterns/type/qatomiccasterlocators_p.h
new file mode 100644
index 0000000..c5ac0a4
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocators_p.h
@@ -0,0 +1,909 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicCasterLocators_H
+#define Patternist_AtomicCasterLocators_H
+
+#include "qatomiccasterlocator_p.h"
+#include "qatomiccasters_p.h"
+//#include "qderivedinteger_p.h"
+
+/**
+ * @file
+ * @short Contains AtomicCasterLocator sub-classes that finds classes
+ * which can perform casting from one atomic value to another.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToStringCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const NOTATIONType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToUntypedAtomicCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const NOTATIONType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToAnyURICasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToBooleanCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToDoubleCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToFloatCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToDecimalCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToIntegerCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToBase64BinaryCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToHexBinaryCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToQNameCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToGYearCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToGDayCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToGMonthCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToGYearMonthCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToGMonthDayCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToDateTimeCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToDateCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToSchemaTimeCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToDurationCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToDayTimeDurationCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ToYearMonthDurationCasterLocator : public AtomicCasterLocator
+ {
+ public:
+ using AtomicCasterLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<TypeOfDerivedInteger type>
+ class ToDerivedIntegerCasterLocator : public ToIntegerCasterLocator
+ {
+ public:
+ using ToIntegerCasterLocator::visit;
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new BooleanToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new StringToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new StringToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new StringToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeByte> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeInt> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeLong> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeNegativeInteger> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeNonNegativeInteger> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeNonPositiveInteger> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypePositiveInteger> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeShort> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeUnsignedByte> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeUnsignedInt> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeUnsignedLong> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedIntegerType<TypeUnsignedShort> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new NumericToDerivedIntegerCaster<type>());
+ }
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<TypeOfDerivedString type>
+ class ToDerivedStringCasterLocator : public ToStringCasterLocator
+ {
+ public:
+ using ToStringCasterLocator::visit;
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ // TODO TypeString not handled
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeNormalizedString> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeToken> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeLanguage> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeNMTOKEN> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeName> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeNCName> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeID> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeIDREF> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DerivedStringType<TypeENTITY> *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const SourceLocationReflection *const r) const
+ {
+ Q_UNUSED(r);
+ return AtomicTypeVisitorResult::Ptr(new AnyToDerivedStringCaster<type>());
+ }
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomiccomparatorlocator.cpp b/src/xmlpatterns/type/qatomiccomparatorlocator.cpp
new file mode 100644
index 0000000..61f9722
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocator.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomiccomparatorlocator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicComparatorLocator::AtomicComparatorLocator()
+{
+}
+
+AtomicComparatorLocator::~AtomicComparatorLocator()
+{
+}
+
+#define implCompVisit(type) \
+AtomicTypeVisitorResult::Ptr \
+AtomicComparatorLocator::visit(const type *, \
+ const qint16, \
+ const SourceLocationReflection *const) const \
+{ \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+
+implCompVisit(AnyAtomicType)
+implCompVisit(AnyURIType)
+implCompVisit(Base64BinaryType)
+implCompVisit(BooleanType)
+implCompVisit(DateTimeType)
+implCompVisit(DateType)
+implCompVisit(DayTimeDurationType)
+implCompVisit(DecimalType)
+implCompVisit(DoubleType)
+implCompVisit(DurationType)
+implCompVisit(FloatType)
+implCompVisit(GDayType)
+implCompVisit(GMonthDayType)
+implCompVisit(GMonthType)
+implCompVisit(GYearMonthType)
+implCompVisit(GYearType)
+implCompVisit(HexBinaryType)
+implCompVisit(IntegerType)
+implCompVisit(NOTATIONType)
+implCompVisit(QNameType)
+implCompVisit(StringType)
+implCompVisit(SchemaTimeType)
+implCompVisit(UntypedAtomicType)
+implCompVisit(YearMonthDurationType)
+#undef implCompVisit
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qatomiccomparatorlocator_p.h b/src/xmlpatterns/type/qatomiccomparatorlocator_p.h
new file mode 100644
index 0000000..54aa45b
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocator_p.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicComparatorLocator_H
+#define Patternist_AtomicComparatorLocator_H
+
+#include "qatomictypedispatch_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @todo Docs missing
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicComparatorLocator : public ParameterizedAtomicTypeVisitor
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AtomicComparatorLocator> Ptr;
+ AtomicComparatorLocator();
+ virtual ~AtomicComparatorLocator();
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyAtomicType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const NOTATIONType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomiccomparatorlocators.cpp b/src/xmlpatterns/type/qatomiccomparatorlocators.cpp
new file mode 100644
index 0000000..0fd31d0
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocators.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomiccomparators_p.h"
+
+#include "qatomiccomparatorlocators_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+static const AtomicComparator::Operators AllCompOperators(AtomicComparator::OperatorNotEqual |
+ AtomicComparator::OperatorGreaterOrEqual |
+ AtomicComparator::OperatorLessOrEqual |
+ AtomicComparator::OperatorLessThanNaNLeast |
+ AtomicComparator::OperatorLessThanNaNGreatest);
+/* --------------------------------------------------------------- */
+#define addVisitor(owner, type, comp, validOps) \
+AtomicTypeVisitorResult::Ptr \
+owner##ComparatorLocator::visit(const type *, \
+ const qint16 op, \
+ const SourceLocationReflection *const) const \
+{ \
+ /* Note the extra paranteses around validOps. */ \
+ if(((validOps) & AtomicComparator::Operator(op)) == op) \
+ return AtomicTypeVisitorResult::Ptr(new comp()); \
+ else \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+/* --------------------------------------------------------------- */
+#define visitorForDouble(owner, type) \
+AtomicTypeVisitorResult::Ptr \
+owner##ComparatorLocator::visit(const type *, \
+ const qint16 op, \
+ const SourceLocationReflection *const) const \
+{ \
+ if(((AtomicComparator::OperatorNotEqual | \
+ AtomicComparator::OperatorGreaterOrEqual | \
+ AtomicComparator::OperatorLessOrEqual) & AtomicComparator::Operator(op)) == op) \
+ return AtomicTypeVisitorResult::Ptr(new AbstractFloatComparator()); \
+ else if(op == AtomicComparator::OperatorLessThanNaNLeast) \
+ return AtomicTypeVisitorResult::Ptr(new AbstractFloatSortComparator<AtomicComparator::OperatorLessThanNaNLeast>()); \
+ else if(op == AtomicComparator::OperatorLessThanNaNGreatest) \
+ return AtomicTypeVisitorResult::Ptr(new AbstractFloatSortComparator<AtomicComparator::OperatorLessThanNaNGreatest>()); \
+ else \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+/* --------------------------------------------------------------- */
+
+/* ----------- xs:string, xs:anyURI, xs:untypedAtomic ----------- */
+addVisitor(String, StringType, StringComparator,
+ AllCompOperators)
+addVisitor(String, UntypedAtomicType, StringComparator,
+ AllCompOperators)
+addVisitor(String, AnyURIType, StringComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+
+/* ------------------------- xs:hexBinary ------------------------ */
+addVisitor(HexBinary, HexBinaryType, BinaryDataComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* ----------------------- xs:base64Binary ----------------------- */
+addVisitor(Base64Binary, Base64BinaryType, BinaryDataComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:boolean ------------------------- */
+addVisitor(Boolean, BooleanType, BooleanComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:double -------------------------- */
+visitorForDouble(Double, DoubleType)
+visitorForDouble(Double, FloatType)
+visitorForDouble(Double, DecimalType)
+visitorForDouble(Double, IntegerType)
+/* --------------------------------------------------------------- */
+
+/* --------------------------- xs:float -------------------------- */
+visitorForDouble(Float, DoubleType)
+visitorForDouble(Float, FloatType)
+visitorForDouble(Float, DecimalType)
+visitorForDouble(Float, IntegerType)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:decimal ------------------------- */
+visitorForDouble(Decimal, DoubleType)
+visitorForDouble(Decimal, FloatType)
+addVisitor(Decimal, DecimalType, DecimalComparator,
+ AllCompOperators)
+addVisitor(Decimal, IntegerType, DecimalComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+
+/* ------------------------- xs:integer -------------------------- */
+visitorForDouble(Integer, DoubleType)
+visitorForDouble(Integer, FloatType)
+addVisitor(Integer, DecimalType, DecimalComparator,
+ AllCompOperators)
+addVisitor(Integer, IntegerType, IntegerComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:QName --------------------------- */
+addVisitor(QName, QNameType, QNameComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:gYear --------------------------- */
+addVisitor(GYear, GYearType, AbstractDateTimeComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:gDay ---------------------------- */
+addVisitor(GDay, GDayType, AbstractDateTimeComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:gMonth -------------------------- */
+addVisitor(GMonth, GMonthType, AbstractDateTimeComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* ------------------------ xs:gYearMonth ------------------------ */
+addVisitor(GYearMonth, GYearMonthType, AbstractDateTimeComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* ------------------------ xs:gMonthDay ------------------------- */
+addVisitor(GMonthDay, GMonthDayType, AbstractDateTimeComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* ------------------------ xs:dateTime -------------------------- */
+addVisitor(DateTime, DateTimeType, AbstractDateTimeComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:time ---------------------------- */
+addVisitor(SchemaTime, SchemaTimeType, AbstractDateTimeComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+
+/* -------------------------- xs:date ---------------------------- */
+addVisitor(Date, DateType, AbstractDateTimeComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+
+/* ------------------------ xs:duration -------------------------- */
+addVisitor(Duration, DayTimeDurationType, AbstractDurationComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+addVisitor(Duration, DurationType, AbstractDurationComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+addVisitor(Duration, YearMonthDurationType, AbstractDurationComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* ------------------ xs:dayTimeDuration ------------------------ */
+addVisitor(DayTimeDuration, DayTimeDurationType, AbstractDurationComparator,
+ AllCompOperators)
+addVisitor(DayTimeDuration, DurationType, AbstractDurationComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+addVisitor(DayTimeDuration, YearMonthDurationType, AbstractDurationComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+/* --------------------------------------------------------------- */
+
+/* ------------------- xs:yearMonthDuration --------------------- */
+addVisitor(YearMonthDuration, DayTimeDurationType, AbstractDurationComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+addVisitor(YearMonthDuration, DurationType, AbstractDurationComparator,
+ AtomicComparator::OperatorEqual |
+ AtomicComparator::OperatorNotEqual)
+addVisitor(YearMonthDuration, YearMonthDurationType, AbstractDurationComparator,
+ AllCompOperators)
+/* --------------------------------------------------------------- */
+#undef addVisitor
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qatomiccomparatorlocators_p.h b/src/xmlpatterns/type/qatomiccomparatorlocators_p.h
new file mode 100644
index 0000000..77aabec
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocators_p.h
@@ -0,0 +1,356 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicComparatorLocators_H
+#define Patternist_AtomicComparatorLocators_H
+
+#include "qatomiccomparatorlocator_p.h"
+
+/**
+ * @file
+ * @short Contains AtomicComparatorLocator sub-classes that finds classes
+ * which can compare atomic values.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DoubleComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class FloatComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DecimalComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class IntegerComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BooleanComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Base64BinaryComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class HexBinaryComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class QNameComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GYearComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GMonthComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GYearMonthComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GMonthDayComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GDayComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DateTimeComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SchemaTimeComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DateComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DurationComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DayTimeDurationComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class YearMonthDurationComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomicmathematicianlocator.cpp b/src/xmlpatterns/type/qatomicmathematicianlocator.cpp
new file mode 100644
index 0000000..3fb1503
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocator.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicmathematicianlocator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicMathematicianLocator::~AtomicMathematicianLocator()
+{
+}
+
+#define implVisit(type) \
+AtomicTypeVisitorResult::Ptr AtomicMathematicianLocator::visit(const type *, const qint16, \
+ const SourceLocationReflection *const) const \
+{ \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+
+implVisit(AnyAtomicType)
+implVisit(AnyURIType)
+implVisit(Base64BinaryType)
+implVisit(BooleanType)
+implVisit(DateTimeType)
+implVisit(DateType)
+implVisit(DayTimeDurationType)
+implVisit(DecimalType)
+implVisit(DoubleType)
+implVisit(DurationType)
+implVisit(FloatType)
+implVisit(GDayType)
+implVisit(GMonthDayType)
+implVisit(GMonthType)
+implVisit(GYearMonthType)
+implVisit(GYearType)
+implVisit(HexBinaryType)
+implVisit(IntegerType)
+implVisit(NOTATIONType)
+implVisit(QNameType)
+implVisit(StringType)
+implVisit(SchemaTimeType)
+implVisit(UntypedAtomicType)
+implVisit(YearMonthDurationType)
+#undef implVisit
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qatomicmathematicianlocator_p.h b/src/xmlpatterns/type/qatomicmathematicianlocator_p.h
new file mode 100644
index 0000000..e4e55e4
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocator_p.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicTypeVisitorResultLocator_H
+#define Patternist_AtomicTypeVisitorResultLocator_H
+
+#include "qatomictypedispatch_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @todo Docs missing
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicMathematicianLocator : public ParameterizedAtomicTypeVisitor
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AtomicMathematicianLocator> Ptr;
+
+ inline AtomicMathematicianLocator()
+ {
+ }
+
+ virtual ~AtomicMathematicianLocator();
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyAtomicType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const NOTATIONType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomicmathematicianlocators.cpp b/src/xmlpatterns/type/qatomicmathematicianlocators.cpp
new file mode 100644
index 0000000..7c5518d
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocators.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloatmathematician_p.h"
+#include "qatomicmathematicianlocators_p.h"
+#include "qatomicmathematicians_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+#define implMathVisit(ownerClass, visitor, mather, validOps) \
+AtomicTypeVisitorResult::Ptr \
+ownerClass##MathematicianLocator::visit(const visitor *, const qint16 op, \
+ const SourceLocationReflection *const r) const \
+{ \
+ Q_UNUSED(r) \
+ /* Note the extra paranteses around validOps. */ \
+ if(((validOps) & AtomicMathematician::Operator(op)) == op) \
+ return AtomicTypeVisitorResult::Ptr(new mather()); \
+ else \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+
+#define implReportingMathVisit(ownerClass, visitor, mather, validOps) \
+AtomicTypeVisitorResult::Ptr \
+ownerClass##MathematicianLocator::visit(const visitor *, const qint16 op, \
+ const SourceLocationReflection *const r) const \
+{ \
+ /* Note the extra paranteses around validOps. */ \
+ if(((validOps) & AtomicMathematician::Operator(op)) == op) \
+ return AtomicTypeVisitorResult::Ptr(new mather(r)); \
+ else \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+
+#define implRevReportingMathVisit(ownerClass, visitor, mather, validOps) \
+AtomicTypeVisitorResult::Ptr \
+ownerClass##MathematicianLocator::visit(const visitor *, const qint16 op, \
+ const SourceLocationReflection *const r) const \
+{ \
+ /* Note the extra paranteses around validOps. */ \
+ if(((validOps) & AtomicMathematician::Operator(op)) == op) \
+ return AtomicTypeVisitorResult::Ptr(new OperandSwitcherMathematician( \
+ AtomicMathematician::Ptr(new mather(r)))); \
+ else \
+ return AtomicTypeVisitorResult::Ptr(); \
+}
+
+static const AtomicMathematician::Operators AllMathOperators(AtomicMathematician::Add |
+ AtomicMathematician::Div |
+ AtomicMathematician::IDiv |
+ AtomicMathematician::Mod |
+ AtomicMathematician::Multiply |
+ AtomicMathematician::Substract);
+
+static const AtomicMathematician::Operators DivMultiply(AtomicMathematician::Multiply |
+ AtomicMathematician::Div);
+
+static const AtomicMathematician::Operators DurationOps(AtomicMathematician::Div |
+ AtomicMathematician::Substract |
+ AtomicMathematician::Add);
+
+static const AtomicMathematician::Operators DTOps(AtomicMathematician::Substract |
+ AtomicMathematician::Add);
+
+implReportingMathVisit(Double, DecimalType, DoubleMathematician, AllMathOperators)
+implReportingMathVisit(Double, DoubleType, DoubleMathematician, AllMathOperators)
+implReportingMathVisit(Double, FloatType, DoubleMathematician, AllMathOperators)
+implReportingMathVisit(Double, IntegerType, DoubleMathematician, AllMathOperators)
+implRevReportingMathVisit(Double, YearMonthDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+implRevReportingMathVisit(Double, DayTimeDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+
+implReportingMathVisit(Float, DecimalType, FloatMathematician, AllMathOperators)
+implReportingMathVisit(Float, DoubleType, DoubleMathematician, AllMathOperators)
+implReportingMathVisit(Float, FloatType, FloatMathematician, AllMathOperators)
+implReportingMathVisit(Float, IntegerType, FloatMathematician, AllMathOperators)
+implRevReportingMathVisit(Float, YearMonthDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+implRevReportingMathVisit(Float, DayTimeDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+
+implReportingMathVisit(Decimal, DecimalType, DecimalMathematician, AllMathOperators)
+implReportingMathVisit(Decimal, DoubleType, DoubleMathematician, AllMathOperators)
+implReportingMathVisit(Decimal, FloatType, FloatMathematician, AllMathOperators)
+implReportingMathVisit(Decimal, IntegerType, DecimalMathematician, AllMathOperators)
+implRevReportingMathVisit(Decimal, YearMonthDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+implRevReportingMathVisit(Decimal, DayTimeDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+
+implReportingMathVisit(Integer, DecimalType, DecimalMathematician, AllMathOperators)
+implReportingMathVisit(Integer, DoubleType, DoubleMathematician, AllMathOperators)
+implReportingMathVisit(Integer, FloatType, FloatMathematician, AllMathOperators)
+implReportingMathVisit(Integer, IntegerType, IntegerMathematician, AllMathOperators)
+implRevReportingMathVisit(Integer, YearMonthDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+implRevReportingMathVisit(Integer, DayTimeDurationType, DurationNumericMathematician, AtomicMathematician::Multiply)
+
+implRevReportingMathVisit(DayTimeDuration, DateTimeType, DateTimeDurationMathematician, AtomicMathematician::Add)
+implRevReportingMathVisit(DayTimeDuration, DateType, DateTimeDurationMathematician, AtomicMathematician::Add)
+implMathVisit(DayTimeDuration, DayTimeDurationType, DurationDurationMathematician, DurationOps)
+implReportingMathVisit(DayTimeDuration, DecimalType, DurationNumericMathematician, DivMultiply)
+implReportingMathVisit(DayTimeDuration, DoubleType, DurationNumericMathematician, DivMultiply)
+implReportingMathVisit(DayTimeDuration, FloatType, DurationNumericMathematician, DivMultiply)
+implReportingMathVisit(DayTimeDuration, IntegerType, DurationNumericMathematician, DivMultiply)
+implRevReportingMathVisit(DayTimeDuration, SchemaTimeType, DateTimeDurationMathematician, AtomicMathematician::Add)
+
+implRevReportingMathVisit(YearMonthDuration, DateTimeType, DateTimeDurationMathematician, AtomicMathematician::Add)
+implRevReportingMathVisit(YearMonthDuration, DateType, DateTimeDurationMathematician, AtomicMathematician::Add)
+implReportingMathVisit(YearMonthDuration, DecimalType, DurationNumericMathematician, DivMultiply)
+implReportingMathVisit(YearMonthDuration, DoubleType, DurationNumericMathematician, DivMultiply)
+implReportingMathVisit(YearMonthDuration, FloatType, DurationNumericMathematician, DivMultiply)
+implReportingMathVisit(YearMonthDuration, IntegerType, DurationNumericMathematician, DivMultiply)
+implMathVisit(YearMonthDuration, YearMonthDurationType, DurationDurationMathematician, DurationOps)
+
+implMathVisit(Date, DateType, AbstractDateTimeMathematician,
+ AtomicMathematician::Substract)
+implReportingMathVisit(Date, YearMonthDurationType, DateTimeDurationMathematician, DTOps)
+implReportingMathVisit(Date, DayTimeDurationType, DateTimeDurationMathematician, DTOps)
+
+implMathVisit(SchemaTime, SchemaTimeType, AbstractDateTimeMathematician,
+ AtomicMathematician::Substract)
+implReportingMathVisit(SchemaTime, DayTimeDurationType, DateTimeDurationMathematician, DTOps)
+
+implMathVisit(DateTime, DateTimeType, AbstractDateTimeMathematician,
+ AtomicMathematician::Substract)
+implReportingMathVisit(DateTime, YearMonthDurationType, DateTimeDurationMathematician, DTOps)
+implReportingMathVisit(DateTime, DayTimeDurationType, DateTimeDurationMathematician, DTOps)
+
+#undef implMathVisit
+#undef implReportingMathVisit
+#undef implRevReportingMathVisit
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qatomicmathematicianlocators_p.h b/src/xmlpatterns/type/qatomicmathematicianlocators_p.h
new file mode 100644
index 0000000..0d95698
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocators_p.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicMathematicianLocators_H
+#define Patternist_AtomicMathematicianLocators_H
+
+#include "qatomicmathematician_p.h"
+#include "qatomicmathematicianlocator_p.h"
+
+/**
+ * @file
+ * @short Contains AtomicMathematicianLocator sub-classes that finds classes
+ * which can perform arithmetics between atomic values.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class DoubleMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class FloatMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class DecimalMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class IntegerMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class DateMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class SchemaTimeMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class DateTimeMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class DayTimeDurationMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+
+ /**
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo docs
+ */
+ class YearMonthDurationMathematicianLocator : public AtomicMathematicianLocator
+ {
+ using AtomicMathematicianLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 op,
+ const SourceLocationReflection *const r) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomictype.cpp b/src/xmlpatterns/type/qatomictype.cpp
new file mode 100644
index 0000000..398495e
--- /dev/null
+++ b/src/xmlpatterns/type/qatomictype.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+#include "qschematypefactory_p.h"
+#include "qxmlname.h"
+
+#include "qatomictype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AtomicType::AtomicType()
+{
+}
+
+AtomicType::~AtomicType()
+{
+}
+
+bool AtomicType::xdtTypeMatches(const ItemType::Ptr &other) const
+{
+ if(other->isAtomicType())
+ {
+ if(*other == *this)
+ return true;
+ else
+ return xdtTypeMatches(other->xdtSuperType());
+ }
+ else
+ return false;
+}
+
+bool AtomicType::itemMatches(const Item &item) const
+{
+ Q_ASSERT(item);
+ if(item.isNode())
+ return false;
+ else
+ {
+ const SchemaType::Ptr t(static_cast<AtomicType *>(item.type().data()));
+ return wxsTypeMatches(t);
+ }
+}
+
+ItemType::Ptr AtomicType::atomizedType() const
+{
+ return AtomicType::Ptr(const_cast<AtomicType *>(this));
+}
+
+QString AtomicType::displayName(const NamePool::Ptr &) const
+{
+ /* A bit faster than calling name()->displayName() */
+ return QLatin1String("xs:anyAtomicType");
+}
+
+bool AtomicType::isNodeType() const
+{
+ return false;
+}
+
+bool AtomicType::isAtomicType() const
+{
+ return true;
+}
+
+SchemaType::TypeCategory AtomicType::category() const
+{
+ return SimpleTypeAtomic;
+}
+
+SchemaType::DerivationMethod AtomicType::derivationMethod() const
+{
+ return DerivationRestriction;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qatomictype_p.h b/src/xmlpatterns/type/qatomictype_p.h
new file mode 100644
index 0000000..e1198d3
--- /dev/null
+++ b/src/xmlpatterns/type/qatomictype_p.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicType_H
+#define Patternist_AtomicType_H
+
+#include "qanysimpletype_p.h"
+#include "qatomiccasterlocator_p.h"
+#include "qatomiccomparatorlocator_p.h"
+#include "qatomicmathematicianlocator_p.h"
+#include "qatomictypedispatch_p.h"
+#include "qitemtype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class Item;
+ class SourceLocationReflection;
+
+ /**
+ * @short Base class for all classes that implements atomic types.
+ *
+ * AtomicType does not implement @c xs:anyAtomicType, it is the C++
+ * base class for classes that implement atomic types, such as @c xs:anyAtomicType.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicType : public ItemType,
+ public AnySimpleType
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<AtomicType> Ptr;
+
+ virtual ~AtomicType();
+
+ /**
+ * Implements a generic algorithm which relies on wxsTypeMatches().
+ *
+ * @returns @c true depending on if @p item is an atomic type, and that
+ * AtomicValue::itemType()'s SequenceType::itemType() matches this type.
+ */
+ virtual bool itemMatches(const Item &item) const;
+
+ /**
+ * @returns the result of SharedQXmlName::displayName(), of the SharedQName
+ * object returned from the name() function.
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * returns always @c false
+ */
+ virtual bool isNodeType() const;
+
+ /**
+ * returns always @c true
+ */
+ virtual bool isAtomicType() const;
+
+ /**
+ * Determines whether @p other is equal to this type, or is a
+ * sub-type of this type.
+ *
+ * The implementation is generic, relying on operator==()
+ * and xdtSuperType().
+ */
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+
+ /**
+ * @returns always 'this'
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ /**
+ * @returns always SchemaType::SimpleTypeAtomic
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * @returns DerivationRestriction
+ */
+ virtual DerivationMethod derivationMethod() const;
+
+ virtual AtomicTypeVisitorResult::Ptr
+ accept(const QExplicitlySharedDataPointer<AtomicTypeVisitor> &visitor,
+ const SourceLocationReflection *const) const = 0;
+
+ virtual AtomicTypeVisitorResult::Ptr
+ accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 param,
+ const SourceLocationReflection *const) const = 0;
+
+ virtual AtomicComparatorLocator::Ptr comparatorLocator() const = 0;
+ virtual AtomicMathematicianLocator::Ptr mathematicianLocator() const = 0;
+ virtual AtomicCasterLocator::Ptr casterLocator() const = 0;
+
+ protected:
+ AtomicType();
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qatomictypedispatch_p.h b/src/xmlpatterns/type/qatomictypedispatch_p.h
new file mode 100644
index 0000000..a3a4417
--- /dev/null
+++ b/src/xmlpatterns/type/qatomictypedispatch_p.h
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_AtomicTypeDispatch_H
+#define Patternist_AtomicTypeDispatch_H
+
+#include <QSharedData>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class AnyAtomicType;
+ class AnyURIType;
+ class Base64BinaryType;
+ class BooleanType;
+ class DateTimeType;
+ class DateType;
+ class DayTimeDurationType;
+ class DecimalType;
+ class DoubleType;
+ class DurationType;
+ class FloatType;
+ class GDayType;
+ class GMonthDayType;
+ class GMonthType;
+ class GYearMonthType;
+ class GYearType;
+ class HexBinaryType;
+ class IntegerType;
+ class NOTATIONType;
+ class QNameType;
+ class SourceLocationReflection;
+ class StringType;
+ class SchemaTimeType;
+ class UntypedAtomicType;
+ class YearMonthDurationType;
+
+ enum TypeOfDerivedInteger
+ {
+ TypeByte,
+ TypeInt,
+ TypeLong,
+ TypeNegativeInteger,
+ TypeNonNegativeInteger,
+ TypeNonPositiveInteger,
+ TypePositiveInteger,
+ TypeShort,
+ TypeUnsignedByte,
+ TypeUnsignedInt,
+ TypeUnsignedLong,
+ TypeUnsignedShort
+ };
+
+ template<TypeOfDerivedInteger DerivedType> class DerivedIntegerType;
+
+ enum TypeOfDerivedString
+ {
+ TypeString,
+ TypeNormalizedString,
+ TypeToken,
+ TypeLanguage,
+ TypeNMTOKEN,
+ TypeName,
+ TypeNCName,
+ TypeID,
+ TypeIDREF,
+ TypeENTITY
+ };
+
+ template<TypeOfDerivedString DerivedType> class DerivedStringType;
+
+ /**
+ * @todo Documentation's missing:
+ * - Add link to wikipedia's "multiple dispatch" and "visitor" page.
+ * - Add link to http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html
+ *
+ * @defgroup Patternist_types_dispatch Atomic Type Dispatching
+ */
+
+ /**
+ * @todo Docs missing
+ *
+ * @ingroup Patternist_types_dispatch
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicTypeVisitorResult : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AtomicTypeVisitorResult> Ptr;
+ AtomicTypeVisitorResult() {}
+ virtual ~AtomicTypeVisitorResult() {}
+ };
+
+ /**
+ * @todo Docs missing
+ *
+ * @see ParameterizedAtomicTypeVisitor
+ * @ingroup Patternist_types_dispatch
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AtomicTypeVisitor : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AtomicTypeVisitor> Ptr;
+ virtual ~AtomicTypeVisitor() {}
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyAtomicType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const NOTATIONType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *,
+ const SourceLocationReflection *const reflection) const = 0;
+ };
+
+ /**
+ * @todo Docs missing
+ *
+ * @see AtomicTypeVisitor
+ * @ingroup Patternist_types_dispatch
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ParameterizedAtomicTypeVisitor : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ParameterizedAtomicTypeVisitor> Ptr;
+ virtual ~ParameterizedAtomicTypeVisitor() {}
+
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyAtomicType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const AnyURIType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DayTimeDurationType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DecimalType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DoubleType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DurationType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const FloatType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const IntegerType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const NOTATIONType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const StringType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const UntypedAtomicType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ virtual AtomicTypeVisitorResult::Ptr visit(const YearMonthDurationType *, const qint16 param,
+ const SourceLocationReflection *const reflection) const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qbasictypesfactory.cpp b/src/xmlpatterns/type/qbasictypesfactory.cpp
new file mode 100644
index 0000000..ca4559f
--- /dev/null
+++ b/src/xmlpatterns/type/qbasictypesfactory.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+
+#include "qbasictypesfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SchemaTypeFactory::Ptr BasicTypesFactory::self(const NamePool::Ptr &np)
+{
+ /* We don't store a global static here, because it's dependent on the NamePool. */
+ return SchemaTypeFactory::Ptr(new BasicTypesFactory(np));
+}
+
+BasicTypesFactory::BasicTypesFactory(const NamePool::Ptr &np)
+{
+ m_types.reserve(48);
+
+#define add(aName) m_types.insert(BuiltinTypes::aName->name(np), AtomicType::Ptr(BuiltinTypes::aName))
+#define addNA(aName) m_types.insert(BuiltinTypes::aName->name(np), BuiltinTypes::aName)
+ add(xsString);
+ add(xsBoolean);
+ add(xsDecimal);
+ add(xsDouble);
+ add(xsFloat);
+ add(xsDate);
+ add(xsTime);
+ add(xsDateTime);
+ add(xsDuration);
+ add(xsAnyURI);
+ add(xsGDay);
+ add(xsGMonthDay);
+ add(xsGMonth);
+ add(xsGYearMonth);
+ add(xsGYear);
+ add(xsBase64Binary);
+ add(xsHexBinary);
+ add(xsQName);
+ add(xsInteger);
+ addNA(xsAnyType);
+ addNA(xsAnySimpleType);
+ add(xsYearMonthDuration);
+ add(xsDayTimeDuration);
+ add(xsAnyAtomicType);
+ addNA(xsUntyped);
+ add(xsUntypedAtomic);
+ add(xsNOTATION);
+ /* Add derived primitives. */
+ add(xsNonPositiveInteger);
+ add(xsNegativeInteger);
+ add(xsLong);
+ add(xsInt);
+ add(xsShort);
+ add(xsByte);
+ add(xsNonNegativeInteger);
+ add(xsUnsignedLong);
+ add(xsUnsignedInt);
+ add(xsUnsignedShort);
+ add(xsUnsignedByte);
+ add(xsPositiveInteger);
+ add(xsNormalizedString);
+ add(xsToken);
+ add(xsLanguage);
+ add(xsNMTOKEN);
+ add(xsName);
+ add(xsNCName);
+ add(xsID);
+ add(xsIDREF);
+ add(xsENTITY);
+
+#undef add
+#undef addNA
+}
+
+SchemaType::Ptr BasicTypesFactory::createSchemaType(const QXmlName name) const
+{
+ return m_types.value(name);
+}
+
+SchemaType::Hash BasicTypesFactory::types() const
+{
+ return m_types;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qbasictypesfactory_p.h b/src/xmlpatterns/type/qbasictypesfactory_p.h
new file mode 100644
index 0000000..95666b9
--- /dev/null
+++ b/src/xmlpatterns/type/qbasictypesfactory_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_BuiltinTypesFactory_H
+#define Patternist_BuiltinTypesFactory_H
+
+#include <QHash>
+#include "qschematypefactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Factory for creating schema types for the types defined in XSL-T 2.0.
+ *
+ * Theses types are essentially the builtin primitive types, plus @c xs:integer,
+ * and the types defined in the XPath Data Model.
+ *
+ * @ingroup Patternist_types
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/#types-predefined">XQuery 1.0 and
+ * XPath 2.0 Data Model, 2.6.2 Predefined Types</a>
+ * @see <a href="http://www.w3.org/TR/xslt20/#built-in-types">XSL Transformations (XSLT)
+ * Version 2.0, 3.13 Built-in Types</a>
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#built-in-primitive-datatypes">XML Schema
+ * Part 2: Datatypes Second Edition, 3.2 Primitive datatypes</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BasicTypesFactory : public SchemaTypeFactory
+ {
+ public:
+
+ /**
+ * Creates a primitive type for @p name. If @p name is not supported,
+ * @c null is returned.
+ * The intened supported types are the builtin primitive and derived types.
+ * That is, the 19 W3C XML Schema types, and the additional 5 in the XPath Data MOdel.
+ *
+ * @note This does not handle user defined types, only builtin types.
+ * @todo Update documentation, proportionally with progress.
+ */
+ virtual SchemaType::Ptr createSchemaType(const QXmlName ) const;
+
+ virtual SchemaType::Hash types() const;
+
+ /**
+ * @returns the singleton instance of BasicTypesFactory.
+ */
+ static SchemaTypeFactory::Ptr self(const NamePool::Ptr &np);
+
+ protected:
+ /**
+ * This constructor is protected. Use the static self() function
+ * to retrieve a singleton instance.
+ */
+ BasicTypesFactory(const NamePool::Ptr &np);
+
+ private:
+ /**
+ * A dictonary of builtin primitive and derived primitives.
+ */
+ SchemaType::Hash m_types;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qbuiltinatomictype.cpp b/src/xmlpatterns/type/qbuiltinatomictype.cpp
new file mode 100644
index 0000000..91accc2
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictype.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qitem_p.h"
+#include "qbuiltintypes_p.h"
+#include "qschematype_p.h"
+
+#include "qbuiltinatomictype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+BuiltinAtomicType::BuiltinAtomicType(const AtomicType::Ptr &base,
+ const AtomicComparatorLocator::Ptr &comp,
+ const AtomicMathematicianLocator::Ptr &mather,
+ const AtomicCasterLocator::Ptr &casterlocator)
+ : m_superType(base),
+ m_comparatorLocator(comp),
+ m_mathematicianLocator(mather),
+ m_casterLocator(casterlocator)
+{
+}
+
+SchemaType::Ptr BuiltinAtomicType::wxsSuperType() const
+{
+ return m_superType;
+}
+
+ItemType::Ptr BuiltinAtomicType::xdtSuperType() const
+{
+ return m_superType;
+}
+
+bool BuiltinAtomicType::isAbstract() const
+{
+ return false;
+}
+
+AtomicComparatorLocator::Ptr BuiltinAtomicType::comparatorLocator() const
+{
+ return m_comparatorLocator;
+}
+
+AtomicMathematicianLocator::Ptr BuiltinAtomicType::mathematicianLocator() const
+{
+ return m_mathematicianLocator;
+}
+
+AtomicCasterLocator::Ptr BuiltinAtomicType::casterLocator() const
+{
+ return m_casterLocator;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qbuiltinatomictype_p.h b/src/xmlpatterns/type/qbuiltinatomictype_p.h
new file mode 100644
index 0000000..8f164c5
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictype_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_BuiltinAtomicType_H
+#define Patternist_BuiltinAtomicType_H
+
+#include "qatomictype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Instances of this class represents types that are sub-classes
+ * of @c xs:anyAtomicType.
+ *
+ * Retrieving instances of builtin types is done
+ * via BuiltinTypesFactory::createSchemaType(), not by instantiating this
+ * class manually.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BuiltinAtomicType : public AtomicType
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<BuiltinAtomicType> Ptr;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isAbstract() const;
+
+ /**
+ * @returns the base type as specified in the constructors baseType argument.
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * @returns the same type as wxsSuperType(), except for the type @c xs:anyAtomicType, which
+ * returns item()
+ */
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ virtual AtomicComparatorLocator::Ptr comparatorLocator() const;
+ virtual AtomicMathematicianLocator::Ptr mathematicianLocator() const;
+ virtual AtomicCasterLocator::Ptr casterLocator() const;
+
+ protected:
+ friend class BuiltinTypes;
+
+ /**
+ * @param baseType the type that is the super type of the constructed
+ * atomic type. In the case of AnyAtomicType, @c null is passed.
+ * @param comp the AtomicComparatorLocator this type should return. May be @c null.
+ * @param mather similar to @p comp, this is the AtomicMathematicianLocator
+ * that's appropriate for this type May be @c null.
+ * @param casterLocator the CasterLocator that locates classes performing
+ * casting with this type. May be @c null.
+ */
+ BuiltinAtomicType(const AtomicType::Ptr &baseType,
+ const AtomicComparatorLocator::Ptr &comp,
+ const AtomicMathematicianLocator::Ptr &mather,
+ const AtomicCasterLocator::Ptr &casterLocator);
+
+ private:
+ const AtomicType::Ptr m_superType;
+ const AtomicComparatorLocator::Ptr m_comparatorLocator;
+ const AtomicMathematicianLocator::Ptr m_mathematicianLocator;
+ const AtomicCasterLocator::Ptr m_casterLocator;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qbuiltinatomictypes.cpp b/src/xmlpatterns/type/qbuiltinatomictypes.cpp
new file mode 100644
index 0000000..5b9db43
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictypes.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicmathematicianlocators_p.h"
+#include "qbuiltintypes_p.h"
+
+#include "qbuiltinatomictypes_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/* -------------------------------------------------------------- */
+#define implAccept(className) \
+AtomicTypeVisitorResult::Ptr className##Type::accept(const AtomicTypeVisitor::Ptr &v, \
+ const SourceLocationReflection *const r) const \
+{ \
+ return v->visit(this, r); \
+} \
+ \
+AtomicTypeVisitorResult::Ptr \
+className##Type::accept(const ParameterizedAtomicTypeVisitor::Ptr &v, \
+ const qint16 op, \
+ const SourceLocationReflection *const r) const \
+{ \
+ return v->visit(this, op, r); \
+}
+
+#define deployComp(className, qname, parent, comp, mather, caster) \
+className##Type::className##Type() : BuiltinAtomicType(BuiltinTypes::parent, \
+ comp, \
+ mather, \
+ caster) \
+{ \
+} \
+implAccept(className)
+
+#define deployBase(className, qname, parent) deployComp(className, qname, parent, \
+ AtomicComparatorLocator::Ptr(), \
+ AtomicMathematicianLocator::Ptr(), \
+ AtomicCasterLocator::Ptr())
+
+#define deployFull(className, qname, parent) \
+deployComp(className, qname, parent, \
+ AtomicComparatorLocator::Ptr(new className##ComparatorLocator()), \
+ AtomicMathematicianLocator::Ptr(), \
+ AtomicCasterLocator::Ptr(new To##className##CasterLocator()))
+
+#define deployMathComp(className, qname, parent) \
+deployComp(className, qname, parent, \
+ AtomicComparatorLocator::Ptr(new className##ComparatorLocator()), \
+ AtomicMathematicianLocator::Ptr(new className##MathematicianLocator()), \
+ AtomicCasterLocator::Ptr(new To##className##CasterLocator()))
+/* -------------------------------------------------------------- */
+
+/* -------------------------------------------------------------- */
+/* xs:anyURI & xs:untypedAtomic are much treated like strings. This ensures
+ * they get the correct operators and automatically takes care of type promotion. */
+deployComp(UntypedAtomic, xsUntypedAtomic, xsAnyAtomicType,
+ AtomicComparatorLocator::Ptr(new StringComparatorLocator()),
+ AtomicMathematicianLocator::Ptr(),
+ AtomicCasterLocator::Ptr(new ToUntypedAtomicCasterLocator()))
+deployComp(AnyURI, xsAnyURI, xsAnyAtomicType,
+ AtomicComparatorLocator::Ptr(new StringComparatorLocator()),
+ AtomicMathematicianLocator::Ptr(),
+ AtomicCasterLocator::Ptr(new ToAnyURICasterLocator()))
+
+deployBase(NOTATION, xsNOTATION, xsAnyAtomicType)
+
+deployMathComp(Float, xsFloat, numeric)
+deployMathComp(Double, xsDouble, numeric)
+deployMathComp(Decimal, xsDecimal, numeric)
+deployMathComp(DayTimeDuration, xsDayTimeDuration, xsDuration)
+deployMathComp(YearMonthDuration, xsYearMonthDuration, xsDuration)
+deployMathComp(Date, xsDate, xsAnyAtomicType)
+deployMathComp(DateTime, xsDateTime, xsAnyAtomicType)
+deployMathComp(SchemaTime, xsTime, xsAnyAtomicType)
+
+deployFull(Base64Binary, xsBase64Binary, xsAnyAtomicType)
+deployFull(Boolean, xsBoolean, xsAnyAtomicType)
+deployFull(Duration, xsDuration, xsAnyAtomicType)
+deployFull(GDay, xsGDay, xsAnyAtomicType)
+deployFull(GMonth, xsGMonth, xsAnyAtomicType)
+deployFull(GMonthDay, xsGMonthDay, xsAnyAtomicType)
+deployFull(GYear, xsGYear, xsAnyAtomicType)
+deployFull(GYearMonth, xsGYearMonth, xsAnyAtomicType)
+deployFull(HexBinary, xsHexBinary, xsAnyAtomicType)
+deployFull(QName, xsQName, xsAnyAtomicType)
+/* --------------------------------------------------------------- */
+
+/* --------------------------------------------------------------- */
+StringType::StringType(const AtomicType::Ptr &pType,
+ const AtomicCasterLocator::Ptr &casterLoc)
+: BuiltinAtomicType(pType,
+ AtomicComparatorLocator::Ptr(new StringComparatorLocator()),
+ AtomicMathematicianLocator::Ptr(),
+ casterLoc)
+{
+}
+implAccept(String)
+/* --------------------------------------------------------------- */
+
+/* --------------------------------------------------------------- */
+IntegerType::IntegerType(const AtomicType::Ptr &pType,
+ const AtomicCasterLocator::Ptr &casterLoc)
+: BuiltinAtomicType(pType,
+ AtomicComparatorLocator::Ptr(new IntegerComparatorLocator()),
+ AtomicMathematicianLocator::Ptr(new IntegerMathematicianLocator()),
+ casterLoc)
+{
+}
+implAccept(Integer)
+/* --------------------------------------------------------------- */
+
+/* ---------------------- Special Overrides ---------------------- */
+AnyAtomicType::AnyAtomicType() : BuiltinAtomicType(AtomicType::Ptr(),
+ AtomicComparatorLocator::Ptr(),
+ AtomicMathematicianLocator::Ptr(),
+ AtomicCasterLocator::Ptr())
+{
+}
+implAccept(AnyAtomic)
+
+ItemType::Ptr AnyAtomicType::xdtSuperType() const
+{
+ return BuiltinTypes::item;
+}
+
+SchemaType::Ptr AnyAtomicType::wxsSuperType() const
+{
+ return BuiltinTypes::xsAnySimpleType;
+}
+
+bool AnyAtomicType::isAbstract() const
+{
+ return true;
+}
+
+bool NOTATIONType::isAbstract() const
+{
+ return true;
+}
+
+#define implementName(className, typeName) \
+QXmlName className##Type::name(const NamePool::Ptr &np) const \
+{ \
+ return np->allocateQName(StandardNamespaces::xs, typeName); \
+} \
+ \
+QString className##Type::displayName(const NamePool::Ptr &np) const \
+{ \
+ return np->displayName(name(np)); \
+}
+
+implementName(AnyAtomic, QLatin1String("anyAtomicType"))
+implementName(AnyURI, QLatin1String("anyURI"))
+implementName(Base64Binary, QLatin1String("base64Binary"))
+implementName(Boolean, QLatin1String("boolean"))
+implementName(Date, QLatin1String("date"))
+implementName(DateTime, QLatin1String("dateTime"))
+implementName(DayTimeDuration, QLatin1String("dayTimeDuration"))
+implementName(Decimal, QLatin1String("decimal"))
+implementName(Double, QLatin1String("double"))
+implementName(Duration, QLatin1String("duration"))
+implementName(Float, QLatin1String("float"))
+implementName(GDay, QLatin1String("gDay"))
+implementName(GMonthDay, QLatin1String("gMonthDay"))
+implementName(GMonth, QLatin1String("gMonth"))
+implementName(GYearMonth, QLatin1String("gYearMonth"))
+implementName(GYear, QLatin1String("gYear"))
+implementName(HexBinary, QLatin1String("hexBinary"))
+implementName(Integer, QLatin1String("integer"))
+implementName(NOTATION, QLatin1String("NOTATION"))
+implementName(QName, QLatin1String("QName"))
+implementName(String, QLatin1String("string"))
+implementName(SchemaTime, QLatin1String("time"))
+implementName(UntypedAtomic, QLatin1String("untypedAtomic"))
+implementName(YearMonthDuration, QLatin1String("yearMonthDuration"))
+/* --------------------------------------------------------------- */
+
+#undef implAccept
+#undef implementName
+#undef deployComp
+#undef deployBase
+#undef deployFull
+#undef deployMathComp
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qbuiltinatomictypes_p.h b/src/xmlpatterns/type/qbuiltinatomictypes_p.h
new file mode 100644
index 0000000..577dd80
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictypes_p.h
@@ -0,0 +1,789 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_BuiltinAtomicTypes_H
+#define Patternist_BuiltinAtomicTypes_H
+
+#include "qatomiccasterlocators_p.h"
+#include "qatomiccomparatorlocators_p.h"
+#include "qbuiltinatomictype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the type @c xs:anyAtomicType.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AnyAtomicType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AnyAtomicType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * Overridden to return <tt>item()</tt>.
+ *
+ * @returns BuiltinTypes::item
+ */
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ /**
+ * Overridden to return @c xs:anySimpleType.
+ *
+ * @returns BuiltinTypes::xsAnySimpleType
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * Overridden to return @c true, @c xs:anyAtomicType is abstract.
+ *
+ * @returns always @c true
+ */
+ virtual bool isAbstract() const;
+
+ protected:
+ friend class BuiltinTypes;
+ AnyAtomicType();
+ };
+
+ /**
+ * @short Implements the type @c xs:untypedAtomic.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class UntypedAtomicType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<UntypedAtomicType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ UntypedAtomicType();
+ };
+
+ /**
+ * @short Implements the type @c xs:dateTime.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DateTimeType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<DateTimeType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+ protected:
+ friend class BuiltinTypes;
+ DateTimeType();
+ };
+
+ /**
+ * @short Implements the type @c xs:date.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DateType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<DateType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ DateType();
+ };
+
+ /**
+ * @short Implements the type @c xs:time.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SchemaTimeType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<SchemaTimeType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ SchemaTimeType();
+ };
+
+ /**
+ * @short Implements the type @c xs:duration.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DurationType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<DurationType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ DurationType();
+ };
+
+ /**
+ * @short Implements the type @c xs:yearMonthDuration.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class YearMonthDurationType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<YearMonthDurationType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ YearMonthDurationType();
+ };
+
+ /**
+ * @short Implements the type @c xs:dayTimeDuration.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DayTimeDurationType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<DayTimeDurationType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ DayTimeDurationType();
+ };
+
+ /**
+ * @short Implements the type @c xs:double.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DoubleType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<DoubleType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ DoubleType();
+ };
+
+ /**
+ * @short Implements the type @c xs:float.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class FloatType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<FloatType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ FloatType();
+ friend class BuiltinTypes;
+ };
+
+ /**
+ * @short Implements the type @c xs:decimal.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DecimalType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<DecimalType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ DecimalType();
+ };
+
+ /**
+ * @short Implements the type @c xs:integer.
+ *
+ * IntegerType instances are used for representing all different xs:integer
+ * types. The purpose of this is that xs:integer sub-types must use the
+ * class, IntegerType, in order to use the correct behavior in call
+ * dispatch situations. That is, all xs:integer sub-types must use the
+ * same AtomicComparator as xs:integer itself uses, and that is achieved
+ * this way.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class IntegerType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<IntegerType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ IntegerType(const AtomicType::Ptr &parentType,
+ const AtomicCasterLocator::Ptr &casterLocator);
+ };
+
+ template<TypeOfDerivedInteger derivedType>
+ class DerivedIntegerType : public IntegerType
+ {
+ public:
+ using IntegerType::accept;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &v,
+ const SourceLocationReflection *const r) const
+ {
+ return v->visit(this, r);
+ }
+
+ virtual QXmlName name(const NamePool::Ptr &np) const
+ {
+ switch(derivedType)
+ {
+ case TypeByte: return np->allocateQName(StandardNamespaces::xs, QLatin1String("byte"));
+ case TypeInt: return np->allocateQName(StandardNamespaces::xs, QLatin1String("int"));
+ case TypeLong: return np->allocateQName(StandardNamespaces::xs, QLatin1String("long"));
+ case TypeNegativeInteger: return np->allocateQName(StandardNamespaces::xs, QLatin1String("negativeInteger"));
+ case TypeNonNegativeInteger: return np->allocateQName(StandardNamespaces::xs, QLatin1String("nonNegativeInteger"));
+ case TypeNonPositiveInteger: return np->allocateQName(StandardNamespaces::xs, QLatin1String("nonPositiveInteger"));
+ case TypePositiveInteger: return np->allocateQName(StandardNamespaces::xs, QLatin1String("positiveInteger"));
+ case TypeShort: return np->allocateQName(StandardNamespaces::xs, QLatin1String("short"));
+ case TypeUnsignedByte: return np->allocateQName(StandardNamespaces::xs, QLatin1String("unsignedByte"));
+ case TypeUnsignedInt: return np->allocateQName(StandardNamespaces::xs, QLatin1String("unsignedInt"));
+ case TypeUnsignedLong: return np->allocateQName(StandardNamespaces::xs, QLatin1String("unsignedLong"));
+ case TypeUnsignedShort: return np->allocateQName(StandardNamespaces::xs, QLatin1String("unsignedShort"));
+ }
+
+ Q_ASSERT_X(false, "DerivedIntegerType::name()", "Invalid value in instantiation.");
+ return QXmlName();
+ }
+
+ virtual QString displayName(const NamePool::Ptr &np) const
+ {
+ return np->displayName(name(np));
+ }
+
+ protected:
+ friend class BuiltinTypes;
+
+ DerivedIntegerType(const AtomicType::Ptr &parentType,
+ const AtomicCasterLocator::Ptr &casterLoc) : IntegerType(parentType, casterLoc)
+ {
+ }
+
+ };
+
+ /**
+ * @short Implements the type @c xs:gYearMonth.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GYearMonthType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<GYearMonthType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ GYearMonthType();
+ };
+
+ /**
+ * @short Implements the type @c xs:gYear.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GYearType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<GYearType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ GYearType();
+ };
+
+ /**
+ * @short Implements the type @c xs:gMonthDay.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GMonthDayType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<GMonthDayType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ GMonthDayType();
+ };
+
+ /**
+ * @short Implements the type @c xs:gDay.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GDayType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<GDayType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ GDayType();
+ };
+
+ /**
+ * @short Implements the type @c xs:gMonth.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GMonthType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<GMonthType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ GMonthType();
+ };
+
+ /**
+ * @short Implements the type @c xs:boolean.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class BooleanType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<BooleanType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ BooleanType();
+ };
+
+ /**
+ * @short Implements the type @c xs:base64Binary.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Base64BinaryType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<Base64BinaryType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ Base64BinaryType();
+ };
+
+ /**
+ * @short Implements the type @c xs:hexBinary.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class HexBinaryType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<HexBinaryType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ HexBinaryType();
+ };
+
+ /**
+ * @short Implements the type @c xs:anyURI.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class AnyURIType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AnyURIType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ AnyURIType();
+ };
+
+ /**
+ * @short Implements the type @c xs:QName.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class QNameType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<QNameType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ QNameType();
+ };
+
+ /**
+ * Represents the xs:string type and all derived types of
+ * xs:string, such as xs:token.
+ *
+ * StringType instances are used for representing all different string
+ * types. The purpose of this is that xs:string sub-types must use the
+ * class, StringType, in order to use the correct behavior in call
+ * dispatch situations. That is, all xs:string sub-types must use the
+ * same AtomicComparator as xs:string itself uses, and that is achieved
+ * this way.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class StringType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<StringType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ protected:
+ friend class BuiltinTypes;
+ StringType(const AtomicType::Ptr &parentType,
+ const AtomicCasterLocator::Ptr &casterLoc);
+ };
+
+ template<TypeOfDerivedString derivedType>
+ class DerivedStringType : public StringType
+ {
+ public:
+ using StringType::accept;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &v,
+ const SourceLocationReflection *const r) const
+ {
+ return v->visit(this, r);
+ }
+
+ virtual QXmlName name(const NamePool::Ptr &np) const
+ {
+ switch(derivedType)
+ {
+ case TypeString: return np->allocateQName(StandardNamespaces::xs, QLatin1String("string"));
+ case TypeNormalizedString: return np->allocateQName(StandardNamespaces::xs, QLatin1String("normalizedString"));
+ case TypeToken: return np->allocateQName(StandardNamespaces::xs, QLatin1String("token"));
+ case TypeLanguage: return np->allocateQName(StandardNamespaces::xs, QLatin1String("language"));
+ case TypeNMTOKEN: return np->allocateQName(StandardNamespaces::xs, QLatin1String("NMTOKEN"));
+ case TypeName: return np->allocateQName(StandardNamespaces::xs, QLatin1String("Name"));
+ case TypeNCName: return np->allocateQName(StandardNamespaces::xs, QLatin1String("NCName"));
+ case TypeID: return np->allocateQName(StandardNamespaces::xs, QLatin1String("ID"));
+ case TypeIDREF: return np->allocateQName(StandardNamespaces::xs, QLatin1String("IDREF"));
+ case TypeENTITY: return np->allocateQName(StandardNamespaces::xs, QLatin1String("ENTITY"));
+ }
+
+ Q_ASSERT_X(false, "DerivedStringType::name()", "Invalid value in instantiation.");
+ return QXmlName();
+ }
+
+ virtual QString displayName(const NamePool::Ptr &np) const
+ {
+ return np->displayName(name(np));
+ }
+
+ protected:
+ friend class BuiltinTypes;
+
+ DerivedStringType(const AtomicType::Ptr &parentType,
+ const AtomicCasterLocator::Ptr &casterLoc) : StringType(parentType, casterLoc)
+ {
+ }
+
+ };
+
+ /**
+ * @short Implements the type @c xs:NOTATION.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NOTATIONType : public BuiltinAtomicType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NOTATIONType> Ptr;
+
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const reflection) const;
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const reflection) const;
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * Overridden to return @c true, xs:NOTATION is abstract.
+ *
+ * @returns always @c true
+ */
+ virtual bool isAbstract() const;
+
+ protected:
+ friend class BuiltinTypes;
+ NOTATIONType();
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qbuiltinnodetype.cpp b/src/xmlpatterns/type/qbuiltinnodetype.cpp
new file mode 100644
index 0000000..1b9932b
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinnodetype.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by BuiltintNodeType.h.
+ * If you need includes in this file, put them in BuiltintNodeType.h, outside of the namespace.
+ */
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+BuiltinNodeType<kind>::BuiltinNodeType()
+{
+}
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+bool BuiltinNodeType<kind>::xdtTypeMatches(const ItemType::Ptr &other) const
+{
+ if(!other->isNodeType())
+ return false;
+
+ return *static_cast<const BuiltinNodeType *>(other.data()) == *this
+ ? true
+ : xdtTypeMatches(other->xdtSuperType());
+}
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+bool BuiltinNodeType<kind>::itemMatches(const Item &item) const
+{
+ Q_ASSERT(item);
+
+ return item.isNode() &&
+ item.asNode().kind() == kind;
+}
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+ItemType::Ptr BuiltinNodeType<kind>::atomizedType() const
+{
+ switch(kind)
+ {
+ /* Fallthrough all these. */
+ case QXmlNodeModelIndex::Attribute:
+ case QXmlNodeModelIndex::Document:
+ case QXmlNodeModelIndex::Element:
+ case QXmlNodeModelIndex::Text:
+ return BuiltinTypes::xsUntypedAtomic;
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Comment:
+ return BuiltinTypes::xsString;
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Encountered invalid XPath Data Model node type.");
+ return BuiltinTypes::xsUntypedAtomic;
+ }
+ }
+}
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+QString BuiltinNodeType<kind>::displayName(const NamePool::Ptr &) const
+{
+ switch(kind)
+ {
+ case QXmlNodeModelIndex::Element:
+ return QLatin1String("element()");
+ case QXmlNodeModelIndex::Document:
+ return QLatin1String("document()");
+ case QXmlNodeModelIndex::Attribute:
+ return QLatin1String("attribute()");
+ case QXmlNodeModelIndex::Text:
+ return QLatin1String("text()");
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ return QLatin1String("processing-instruction()");
+ case QXmlNodeModelIndex::Comment:
+ return QLatin1String("comment()");
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Encountered invalid XPath Data Model node type.");
+ return QString();
+ }
+ }
+}
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+ItemType::Ptr BuiltinNodeType<kind>::xdtSuperType() const
+{
+ return BuiltinTypes::node;
+}
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+QXmlNodeModelIndex::NodeKind BuiltinNodeType<kind>::nodeKind() const
+{
+ return kind;
+}
+
+template <const QXmlNodeModelIndex::NodeKind kind>
+PatternPriority BuiltinNodeType<kind>::patternPriority() const
+{
+ /* See XSL Transformations (XSLT) Version 2.0, 6.4 Conflict Resolution for
+ * Template Rules */
+ switch(kind)
+ {
+ case QXmlNodeModelIndex::Text:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Comment:
+ /* "If the pattern is any other NodeTest, optionally preceded by a
+ * PatternAxis, then the priority is 0.5."
+ * Fallthrough. */
+ case QXmlNodeModelIndex::Attribute:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Element:
+ /* Fallthrough. */
+ case QXmlNodeModelIndex::Document:
+ /* "If the pattern has the form /, then the priority is -0.5.". */
+ return -0.5;
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown node type");
+ return 0;
+ }
+ }
+
+}
+
diff --git a/src/xmlpatterns/type/qbuiltinnodetype_p.h b/src/xmlpatterns/type/qbuiltinnodetype_p.h
new file mode 100644
index 0000000..151ad36
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinnodetype_p.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_BuiltinNodeType_H
+#define Patternist_BuiltinNodeType_H
+
+#include "qitem_p.h"
+#include "qanynodetype_p.h"
+#include "qbuiltintypes_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Instances of this class represents types that are sub-classes
+ * of <tt>node()</tt>, such as <tt>processing-instruction()</tt>.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template <const QXmlNodeModelIndex::NodeKind kind>
+ class BuiltinNodeType : public AnyNodeType
+ {
+ public:
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+ virtual bool itemMatches(const Item &item) const;
+
+ /**
+ * @returns for example "text()", depending on what the constructor was passed
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ virtual ItemType::Ptr xdtSuperType() const;
+ virtual ItemType::Ptr atomizedType() const;
+
+ QXmlNodeModelIndex::NodeKind nodeKind() const;
+
+ PatternPriority patternPriority() const;
+
+ protected:
+ friend class BuiltinTypes;
+
+ /**
+ * This constructor does nothing, but exists in order to make it impossible to
+ * instantiate this class from anywhere but from BuiltinTypes.
+ */
+ BuiltinNodeType();
+ };
+
+#include "qbuiltinnodetype.cpp"
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qbuiltintypes.cpp b/src/xmlpatterns/type/qbuiltintypes.cpp
new file mode 100644
index 0000000..2953fd6
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltintypes.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyitemtype_p.h"
+#include "qderivedinteger_p.h"
+
+#include "qbuiltinatomictypes_p.h"
+#include "qbuiltinnodetype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qxsltnodetest_p.h"
+
+/* Included here to avoid the static initialization failure. */
+#include "qatomiccasterlocators.cpp"
+#include "qatomiccomparatorlocators.cpp"
+#include "qatomicmathematicianlocators.cpp"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+// STATIC DATA
+/* Special cases. */
+#define initType(var, cls) const cls::Ptr BuiltinTypes::var(new cls())
+initType(item, AnyItemType);
+initType(node, AnyNodeType);
+#undef initType
+
+#define initSType(var, cls) const SchemaType::Ptr BuiltinTypes::var(new cls())
+initSType(xsAnyType, AnyType);
+initSType(xsAnySimpleType, AnySimpleType);
+initSType(xsUntyped, Untyped);
+#undef initSType
+
+/* The primitive atomic types. */
+#define at(className, varName) const AtomicType::Ptr BuiltinTypes::varName(new className());
+at(AnyAtomicType, xsAnyAtomicType)
+at(UntypedAtomicType, xsUntypedAtomic)
+at(DateTimeType, xsDateTime)
+at(DateType, xsDate)
+at(SchemaTimeType, xsTime)
+at(DurationType, xsDuration)
+at(YearMonthDurationType, xsYearMonthDuration)
+at(DayTimeDurationType, xsDayTimeDuration)
+
+at(NumericType, numeric)
+at(DecimalType, xsDecimal)
+at(GYearMonthType, xsGYearMonth)
+at(GYearType, xsGYear)
+at(GMonthDayType, xsGMonthDay)
+at(GDayType, xsGDay)
+at(GMonthType, xsGMonth)
+
+at(BooleanType, xsBoolean)
+at(Base64BinaryType, xsBase64Binary)
+at(AnyURIType, xsAnyURI)
+
+#define it(className, varName) const ItemType::Ptr BuiltinTypes::varName(new className());
+at(QNameType, xsQName)
+at(HexBinaryType, xsHexBinary)
+at(FloatType, xsFloat)
+at(DoubleType, xsDouble)
+#undef it
+
+const AtomicType::Ptr BuiltinTypes::xsString(new StringType(BuiltinTypes::xsAnyAtomicType,
+ AtomicCasterLocator::Ptr(new ToStringCasterLocator())));
+
+#define dsType(varName, parent) \
+ const AtomicType::Ptr BuiltinTypes::xs ## varName \
+ (new DerivedStringType<Type ## varName>(BuiltinTypes::parent, \
+ AtomicCasterLocator::Ptr(new ToDerivedStringCasterLocator<Type ## varName>())))
+
+dsType(NormalizedString, xsString);
+dsType(Token, xsNormalizedString);
+dsType(Language, xsToken);
+dsType(NMTOKEN, xsToken);
+dsType(Name, xsToken);
+dsType(NCName, xsName);
+dsType(ID, xsNCName);
+dsType(IDREF, xsNCName);
+dsType(ENTITY, xsNCName);
+#undef sType
+
+const AtomicType::Ptr BuiltinTypes::xsInteger(new IntegerType(BuiltinTypes::xsDecimal,
+ AtomicCasterLocator::Ptr(new ToIntegerCasterLocator())));
+
+#define iType(varName, parent) \
+ const AtomicType::Ptr BuiltinTypes::xs ## varName \
+ (new DerivedIntegerType<Type ## varName>(parent, \
+ AtomicCasterLocator::Ptr(new ToDerivedIntegerCasterLocator<Type ## varName>())))
+
+/* Initialize derived integers. The order of initialization is significant. */
+iType(NonPositiveInteger, xsInteger);
+iType(NegativeInteger, xsNonPositiveInteger);
+iType(Long, xsInteger);
+iType(Int, xsLong);
+iType(Short, xsInt);
+iType(Byte, xsShort);
+iType(NonNegativeInteger, xsInteger);
+iType(UnsignedLong, xsNonNegativeInteger);
+iType(UnsignedInt, xsUnsignedLong);
+iType(UnsignedShort, xsUnsignedInt);
+iType(UnsignedByte, xsUnsignedShort);
+iType(PositiveInteger, xsNonNegativeInteger);
+#undef iType
+
+at(NOTATIONType, xsNOTATION)
+#undef at
+
+/* QXmlNodeModelIndex types */
+#define nt(var, enu) const ItemType::Ptr BuiltinTypes::var = \
+ ItemType::Ptr(new BuiltinNodeType<QXmlNodeModelIndex::enu>())
+
+nt(comment, Comment);
+nt(attribute, Attribute);
+nt(document, Document);
+nt(element, Element);
+nt(text, Text);
+nt(pi, ProcessingInstruction);
+#undef nt
+
+const ItemType::Ptr BuiltinTypes::xsltNodeTest(new XSLTNodeTest());
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qbuiltintypes_p.h b/src/xmlpatterns/type/qbuiltintypes_p.h
new file mode 100644
index 0000000..0bfe2c8
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltintypes_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_BuiltinTypes_H
+#define Patternist_BuiltinTypes_H
+
+#include "qanynodetype_p.h"
+#include "qanysimpletype_p.h"
+#include "qanytype_p.h"
+#include "qbuiltinatomictype_p.h"
+#include "qitemtype_p.h"
+#include "qnumerictype_p.h"
+#include "quntyped_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Provides access to singleton instances of ItemType and SchemaType sub-classes.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT BuiltinTypes
+ {
+ public:
+ static const SchemaType::Ptr xsAnyType;
+ static const SchemaType::Ptr xsAnySimpleType;
+ static const SchemaType::Ptr xsUntyped;
+
+ static const AtomicType::Ptr xsAnyAtomicType;
+ static const AtomicType::Ptr xsUntypedAtomic;
+ static const AtomicType::Ptr xsDateTime;
+ static const AtomicType::Ptr xsDate;
+ static const AtomicType::Ptr xsTime;
+ static const AtomicType::Ptr xsDuration;
+ static const AtomicType::Ptr xsYearMonthDuration;
+ static const AtomicType::Ptr xsDayTimeDuration;
+
+ /**
+ * An artificial type for implementation purposes
+ * that represents the XPath type @c numeric.
+ */
+ static const AtomicType::Ptr numeric;
+ static const AtomicType::Ptr xsFloat;
+ static const AtomicType::Ptr xsDouble;
+ static const AtomicType::Ptr xsInteger;
+ static const AtomicType::Ptr xsDecimal;
+ static const AtomicType::Ptr xsNonPositiveInteger;
+ static const AtomicType::Ptr xsNegativeInteger;
+ static const AtomicType::Ptr xsLong;
+ static const AtomicType::Ptr xsInt;
+ static const AtomicType::Ptr xsShort;
+ static const AtomicType::Ptr xsByte;
+ static const AtomicType::Ptr xsNonNegativeInteger;
+ static const AtomicType::Ptr xsUnsignedLong;
+ static const AtomicType::Ptr xsUnsignedInt;
+ static const AtomicType::Ptr xsUnsignedShort;
+ static const AtomicType::Ptr xsUnsignedByte;
+ static const AtomicType::Ptr xsPositiveInteger;
+
+
+ static const AtomicType::Ptr xsGYearMonth;
+ static const AtomicType::Ptr xsGYear;
+ static const AtomicType::Ptr xsGMonthDay;
+ static const AtomicType::Ptr xsGDay;
+ static const AtomicType::Ptr xsGMonth;
+
+ static const AtomicType::Ptr xsBoolean;
+
+ static const AtomicType::Ptr xsBase64Binary;
+ static const AtomicType::Ptr xsHexBinary;
+ static const AtomicType::Ptr xsAnyURI;
+ static const AtomicType::Ptr xsQName;
+ static const AtomicType::Ptr xsString;
+ static const AtomicType::Ptr xsNormalizedString;
+ static const AtomicType::Ptr xsToken;
+ static const AtomicType::Ptr xsLanguage;
+ static const AtomicType::Ptr xsNMTOKEN;
+ static const AtomicType::Ptr xsName;
+ static const AtomicType::Ptr xsNCName;
+ static const AtomicType::Ptr xsID;
+ static const AtomicType::Ptr xsIDREF;
+ static const AtomicType::Ptr xsENTITY;
+
+ static const AtomicType::Ptr xsNOTATION;
+ static const ItemType::Ptr item;
+
+ static const AnyNodeType::Ptr node;
+
+ /**
+ * When the node test node() is used without axes in a pattern in
+ * XSL-T, it doesn't match document nodes. See 5.5.3 The Meaning of a
+ * Pattern.
+ *
+ * This node test does that.
+ */
+ static const ItemType::Ptr xsltNodeTest;
+
+ static const ItemType::Ptr attribute;
+ static const ItemType::Ptr comment;
+ static const ItemType::Ptr document;
+ static const ItemType::Ptr element;
+ static const ItemType::Ptr pi;
+ static const ItemType::Ptr text;
+
+ private:
+ /**
+ * The constructor is protected because this class is not meant to be instantiated,
+ * but should only be used via its static const members.
+ */
+ BuiltinTypes();
+ Q_DISABLE_COPY(BuiltinTypes)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/type/qcardinality.cpp b/src/xmlpatterns/type/qcardinality.cpp
new file mode 100644
index 0000000..7940a1a
--- /dev/null
+++ b/src/xmlpatterns/type/qcardinality.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpatternistlocale_p.h"
+
+#include "qcardinality_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QString Cardinality::displayName(const CustomizeDisplayName explain) const
+{
+ if(explain == IncludeExplanation)
+ {
+ if(isEmpty())
+ return QString(QtXmlPatterns::tr("empty") + QLatin1String("(\"empty-sequence()\")"));
+ else if(isZeroOrOne())
+ return QString(QtXmlPatterns::tr("zero or one") + QLatin1String("(\"?\")"));
+ else if(isExactlyOne())
+ return QString(QtXmlPatterns::tr("exactly one"));
+ else if(isOneOrMore())
+ return QString(QtXmlPatterns::tr("one or more") + QLatin1String("(\"+\")"));
+ else
+ return QString(QtXmlPatterns::tr("zero or more") + QLatin1String("(\"*\")"));
+ }
+ else
+ {
+ Q_ASSERT(explain == ExcludeExplanation);
+
+ if(isEmpty() || isZeroOrOne())
+ return QLatin1String("?");
+ else if(isExactlyOne())
+ return QString();
+ else if(isExact())
+ {
+ return QString(QLatin1Char('{')) +
+ QString::number(maximum()) +
+ QLatin1Char('}');
+ }
+ else
+ {
+ if(m_max == -1)
+ {
+ if(isOneOrMore())
+ return QChar::fromLatin1('+');
+ else
+ return QChar::fromLatin1('*');
+ }
+ else
+ {
+ /* We have a range. We use a RegExp-like syntax. */
+ return QString(QLatin1Char('{')) +
+ QString::number(minimum()) +
+ QLatin1String(", ") +
+ QString::number(maximum()) +
+ QLatin1Char('}');
+
+ }
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qcardinality_p.h b/src/xmlpatterns/type/qcardinality_p.h
new file mode 100644
index 0000000..e7ba587
--- /dev/null
+++ b/src/xmlpatterns/type/qcardinality_p.h
@@ -0,0 +1,544 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Cardinality_H
+#define Patternist_Cardinality_H
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a cardinality, a possible , often represented by occurrence indicators.
+ *
+ * As opposed to the cardinality concept in the XQuery/XPath specifications, which
+ * only allows cardinalities to be expressed with kleene operators, this representation
+ * allows ranges. For example, the cardinality 10-11, describes a sequence containing
+ * ten or eleven items, inclusive.
+ *
+ * @ingroup Patternist_types
+ * @see ItemType
+ * @see SequenceType
+ * @see <a href="http://www.w3.org/TR/xpath20/#prod-xpath-SequenceType">XML Path Language
+ * (XPath) 2.0, The EBNF grammar for SequenceType</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Cardinality
+ {
+ public:
+ /**
+ * This integer type, is what Cardinality uses for representing its ranges.
+ */
+ typedef qint32 Count;
+
+ /**
+ * Used with displayName(), and specifies
+ * how a display name for a Cardinality should be.
+ */
+ enum CustomizeDisplayName
+ {
+ /**
+ * Includes a describing string in the return value of displayName().
+ */
+ IncludeExplanation = 1,
+
+ /**
+ * Excludes a describing string in the return value of displayName().
+ */
+ ExcludeExplanation
+ };
+
+ /**
+ * A traditional copy constructor. This Cardinality becomes identical
+ * to @p other.
+ */
+ inline Cardinality(const Cardinality &other) : m_min(other.m_min),
+ m_max(other.m_max)
+ {
+ }
+
+ /**
+ * This default constructor constructs an invalid Cardinality. Using
+ * its operators and members yields undefined results. A value must
+ * first be assigned to it by creating a Cardinality with fromRange(), fromCount(),
+ * or one of the predefined cardinalities such as empty() or oneOrMore().
+ */
+ inline Cardinality() : m_min(-1), m_max(0)
+ {
+ }
+
+ /**
+ * The cardinality assigned to the exprssion <tt>()</tt>, formally speaking. The
+ * cardinality part of <tt>empty-sequence()</tt>.
+ */
+ static inline Cardinality empty()
+ {
+ return Cardinality(0, 0);
+ }
+
+ /**
+ * The cardinality implicitly specified in for example the sequence type
+ * <tt>item()</tt>. It has no kleene operator.
+ */
+ static inline Cardinality exactlyOne()
+ {
+ return Cardinality(1, 1);
+ }
+
+ /**
+ * Allows both no item, as in empty(), and exactlyOne(). Represented
+ * by the kleene operator <tt>?</tt>.
+ */
+ static inline Cardinality zeroOrOne()
+ {
+ return Cardinality(0, 1);
+ }
+
+ /**
+ * Allows any amount. This is therefore the widest, an unconstrained
+ * cardinality. Represented by the kleene operator <tt>*</tt>.
+ */
+ static inline Cardinality zeroOrMore()
+ {
+ return Cardinality(0, -1);
+ }
+
+ /**
+ * Allows one or more. Represented by the kleene operator <tt>+</tt>.
+ */
+ static inline Cardinality oneOrMore()
+ {
+ return Cardinality(1, -1);
+ }
+
+ /**
+ * Allows one or more. This cardinality has no kleene operator and is used
+ * by the implementation in order to be able to know when a cardinality
+ * that at amximum allows one, is exceeded.
+ */
+ static inline Cardinality twoOrMore()
+ {
+ return Cardinality(2, -1);
+ }
+
+ /**
+ * Determines the cardinality from the count of a sequence. For example, if
+ * @p count is 11, a Cardinality is returned that allows at minimum and maximum
+ * 11 items.
+ *
+ * @p count must be positive or zero. If it is not, the result is undefined.
+ * When debugging is enabled, a Q_ASSERT() macro ensures this.
+ */
+ static inline Cardinality fromCount(const Count count)
+ {
+ Q_ASSERT_X(count > -1, Q_FUNC_INFO,
+ "A count smaller than 0 makes no sense.");
+ return Cardinality(count, count);
+ }
+
+ /**
+ * Creates a Cardinality that allows @p minimum and @p maximum
+ * items, inclusive.
+ *
+ * If @p maximum is -1, it signals infinity.
+ *
+ * If you before hand knows that a predefined Cardinality is needed,
+ * remember to use one of the factory functions empty(), zeroOrOne(),
+ * exactlyOne(), oneOrMore() or zeroOrMore(), since they improves
+ * readability, are safer, and slightly faster.
+ */
+ static inline Cardinality fromRange(const Count minimum, const Count maximum)
+ {
+ Q_ASSERT_X(minimum > -1, Q_FUNC_INFO,
+ "minimum should never be less than 0.");
+ Q_ASSERT_X(minimum <= maximum || maximum == -1, Q_FUNC_INFO,
+ "minimum cannot be larger than maximum.");
+
+ return Cardinality(minimum, maximum);
+ }
+
+ static inline Cardinality fromExact(const Count count)
+ {
+ Q_ASSERT(count >= 0);
+ return Cardinality(count, count);
+ }
+
+ /**
+ * @returns the minimum amount of items this Cardinality allows. For example,
+ * for zeroOrOne() is 0 returned.
+ */
+ inline Count minimum() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality are invalid.");
+ return m_min;
+ }
+
+ /**
+ * @returns the maximum amount of items this Cardinality allows. For example,
+ * for zeroOrOne() is 1 returned.
+ */
+ inline Count maximum() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality are invalid.");
+ return m_max;
+ }
+
+ /**
+ * @returns @c true if this Cardinality allows one or more items. For example, for
+ * zeroOrOne() is @c false returned, while for zeroOrMore() is @c true returned.
+ */
+ inline bool allowsMany() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality are invalid.");
+ return m_max == -1 || m_max > 1;
+ }
+
+ /**
+ * @returns @c true if this Cardinality allows no items. For example, for
+ * zeroOrOne() is @c true returned, while for oneOrMore() is @c false returned.
+ */
+ inline bool allowsEmpty() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality are invalid.");
+ return m_min == 0;
+ }
+
+ /**
+ * Maps directly to Formal Semantics' @c aggregate_quantifier function.
+ *
+ * @returns zeroOrOne() if this Cardinality allows the empty sequence, otherwise exactlyOne()
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#jd_quantifier">XQuery 1.0 and
+ * XPath 2.0 Formal Semantics, The function quantifier()</a>
+ */
+ inline Cardinality toWithoutMany() const
+ {
+ return m_min == 0 ? Cardinality(0, 1)
+ : Cardinality(1, 1);
+ }
+
+ /**
+ * Determines whether all the possible outcomes represented by @p other,
+ * will always match this Cardinality. For example, if this Cardinality
+ * is oneOrMore(), @c true will be returned if @p other is exactlyOne(), but
+ * false if @p other is zeroOrOne().
+ */
+ inline bool isMatch(const Cardinality &other) const
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO, "One of the cardinalities are invalid.");
+ if(other.m_min < m_min)
+ return false;
+ else
+ { /* Ok, we now know the minimum will always be ok. */
+ if(m_max == -1)
+ return true; /* We allow infinite, so anything can match. */
+ else if(other.m_max == -1)
+ return false; /* other allows infinity, while we don't. */
+ else
+ return m_max >= other.m_max;
+ }
+ }
+
+ /**
+ * Determines whether at least one of the possible outcomes represented by @p other,
+ * can match this Cardinality. For example, if this Cardinality
+ * is oneOrMore(), @c true will be returned if @p other is exactlyOne() or zeroOrOne().
+ */
+ inline bool canMatch(const Cardinality &other) const
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO, "One of the cardinalities are invalid.");
+ if(m_max == -1)
+ return m_min <= other.m_min || other.m_max >= m_min || other.m_max == -1;
+ else
+ {
+ if(m_max == other.m_min)
+ return true;
+ else if(m_max > other.m_min)
+ return other.m_max >= m_min || other.m_max == -1;
+ else /* m_max < other.m_min */
+ return false;
+ }
+ }
+
+ /**
+ * @returns @c true if this Cardinality is empty, the <tt>empty-sequence()</tt>, otherwise
+ * @c false.
+ */
+ inline bool isEmpty() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality is invalid.");
+ return m_min == 0 && m_max == 0;
+ }
+
+ /**
+ * @returns @c true if this Cardinality is zero-or-one, <tt>?</tt>, otherwise
+ * @c false.
+ */
+ inline bool isZeroOrOne() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality is invalid.");
+ return m_min == 0 && m_max == 1;
+ }
+
+ /**
+ * @returns @c true if this Cardinality only allows exactly one item, otherwise
+ * @c false.
+ */
+ inline bool isExactlyOne() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality is invalid.");
+ return m_min == 1 && m_max == 1;
+ }
+
+ /**
+ * @returns @c true if this Cardinality only allows one or more items, otherwise
+ * @c false.
+ */
+ inline bool isOneOrMore() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality is invalid.");
+ return m_min > 0 && (m_max == -1 || m_max >= 1);
+ }
+
+ /**
+ * Determines whether this Cardinality only allows a specific length. For example,
+ * empty() and exactlyOne() are exact, but oneOrMore() or zeroOrOne() is not.
+ */
+ inline bool isExact() const
+ {
+ Q_ASSERT_X(m_min != -1, Q_FUNC_INFO, "The cardinality is invalid.");
+ return m_min == m_max;
+ }
+
+ /**
+ * Returns a string representation of this Cardinality.
+ *
+ * If @p explain is ExcludeExplanation the kleene operator is returned. For example, if
+ * the Cardinality is zeroOrOne, is "?" returned.
+ *
+ * If explain is IncludeExplanation a string more suited for human interpretation is returned,
+ * which is appropriately translated. For example, when the locale is English and
+ * this Cardinality being zeroOrOne, then is 'zero or one("?")' returned.
+ *
+ * Typically, passing ExcludeExplanation is useful when generating function
+ * signatures and the like, while passing IncludeExplanation
+ * is suitable appropriate when generating error messages.
+ *
+ * @returns a string representation for this Cardinality.
+ */
+ QString displayName(const CustomizeDisplayName explanation) const;
+
+ /**
+ * Computes the Cardinality that comprises this Cardinality as well as @p other. For
+ * example, if this Cardinality is zeroOrOne() and @p other is oneOrMore(), then
+ * is zeroOrMore() returned.
+ */
+ inline Cardinality operator|(const Cardinality &other) const
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO, "One of the cardinalities are invalid.");
+ if(m_max == -1 || other.m_max == -1)
+ return Cardinality(qMin(m_min, other.m_min), -1);
+ else
+ return Cardinality(qMin(m_min, other.m_min), qMax(m_max, other.m_max));
+ }
+
+ /**
+ * Behaves as operator|() but assigns the result to this Cardinality.
+ */
+ inline Cardinality &operator|=(const Cardinality &other)
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO, "One of the cardinalities are invalid.");
+ m_min = qMin(m_min, other.m_min);
+
+ if(m_max == -1)
+ return *this;
+ else if(other.m_max == -1)
+ m_max = -1;
+ else
+ m_max = qMax(m_max, other.m_max);
+
+ return *this;
+ }
+
+ /**
+ * Computes the intersection of this Cardinality and @p other, and returns
+ * the result. For example, the intersection between zeroOrOne() and
+ * oneOrMore() is exactlyOne().
+ *
+ * If no intersection exists, such as the case in empty() and exactlyOne(), then
+ * is a default constructed Cardinality is returned. That is, an invalid Cardinality.
+ */
+ inline Cardinality operator&(const Cardinality &other) const
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO, "One of the cardinalities are invalid.");
+
+ if(m_max < other.m_min) /* No intersection. */
+ return empty();
+
+ const Count min = qMax(m_min, other.m_min);
+
+ if(m_max == -1)
+ return Cardinality(min, other.m_max);
+ else if(other.m_max == -1)
+ return Cardinality(min, m_max);
+ else
+ return Cardinality(min, qMin(m_max, other.m_max));
+ }
+
+ /**
+ * Adds two cardinalities, as if two sequences represented by them were concatenated.
+ * For example, if this Cardinality allows the range 6-8 and @p other allows
+ * 0-1, the return Cardinality has a range of 6-9.
+ *
+ * @returns the result of the comparison.
+ */
+ inline Cardinality operator+(const Cardinality &other) const
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO, "One of the cardinalities are invalid.");
+ if(m_max == -1 || other.m_max == -1)
+ return Cardinality(m_min + other.m_min, -1);
+ else
+ return Cardinality(m_min + other.m_min, m_max + other.m_max);
+ }
+
+ /**
+ * Behaves as operator+() but assigns the result to this Cardinality.
+ */
+ inline Cardinality &operator+=(const Cardinality &other)
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO,
+ "One of the cardinalities are invalid.");
+ m_min += other.m_min;
+
+ if(m_max == -1)
+ return *this;
+ if(other.m_max == -1)
+ m_max = -1;
+ else
+ m_max += other.m_max;
+
+ return *this;
+ }
+
+ /**
+ * Multiplies this Cardinality with @p other, and returns the result. The minimum and maximum
+ * of each Cardinality is multiplied such that the new Cardinality represents the possible
+ * range of the two sequences being multiplied, length-wise. For example the Cardinality
+ * 4, 5 multiplied with 2, 3 becomes 8, 15.
+ */
+ inline Cardinality operator*(const Cardinality &other) const
+ {
+ Q_ASSERT_X(m_min != -1 && other.m_min != -1, Q_FUNC_INFO,
+ "One of the cardinalities are invalid.");
+ if(m_max == -1 || other.m_max == -1)
+ return Cardinality(m_min * other.m_min, -1);
+ else
+ return Cardinality(m_min * other.m_min, m_max * other.m_max);
+ }
+
+ /**
+ * A traditional assignment operator. Behaves as assignment
+ * operators typically do.
+ */
+ inline Cardinality &operator=(const Cardinality &other)
+ {
+ Q_ASSERT_X(this != &other, Q_FUNC_INFO, "Assigning to oneself makes no sense.");
+ m_min = other.m_min;
+ m_max = other.m_max;
+ return *this;
+ }
+
+ /**
+ * Determines whether @p other is equal to this Cardinality.
+ *
+ * For example, empty() is equal to empty(), but zeroOrOne()
+ * is not equal to exactlyOne().
+ *
+ * @returns @c true if @p other is equal to this Cardinality.
+ */
+ inline bool operator==(const Cardinality &other) const
+ {
+ return m_min == other.m_min &&
+ m_max == other.m_max;
+ }
+
+ /**
+ * @returns the opposite of operator==()
+ */
+ inline bool operator!=(const Cardinality &other) const
+ {
+ return m_min != other.m_min ||
+ m_max != other.m_max;
+ }
+
+ private:
+ inline Cardinality(const Count min, const Count max) : m_min(min),
+ m_max(max)
+ {
+ }
+
+ Count m_min;
+ Count m_max;
+ };
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::Cardinality, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qcommonsequencetypes.cpp b/src/xmlpatterns/type/qcommonsequencetypes.cpp
new file mode 100644
index 0000000..7da810e
--- /dev/null
+++ b/src/xmlpatterns/type/qcommonsequencetypes.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qebvtype_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qnonetype_p.h"
+
+#include "qcommonsequencetypes_p.h"
+
+/* To avoid the static initialization fiasco, we put the builtin types in this compilation unit, since
+ * the sequence types depends on them. */
+#include "qbuiltintypes.cpp"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+// STATIC DATA
+#define st(var, type, card) \
+const SequenceType::Ptr \
+CommonSequenceTypes::var(new GenericSequenceType(BuiltinTypes::type, \
+ Cardinality::card()))
+
+/* Alphabetically. */
+st(ExactlyOneAnyURI, xsAnyURI, exactlyOne);
+st(ExactlyOneAtomicType, xsAnyAtomicType, exactlyOne);
+st(ExactlyOneAttribute, attribute, exactlyOne);
+st(ExactlyOneBase64Binary, xsBase64Binary, exactlyOne);
+st(ExactlyOneBoolean, xsBoolean, exactlyOne);
+st(ExactlyOneComment, comment, exactlyOne);
+st(ExactlyOneDateTime, xsDateTime, exactlyOne);
+st(ExactlyOneDate, xsDate, exactlyOne);
+st(ExactlyOneDayTimeDuration, xsDayTimeDuration, exactlyOne);
+st(ExactlyOneDecimal, xsDecimal, exactlyOne);
+st(ExactlyOneDocumentNode, document, exactlyOne);
+st(OneOrMoreDocumentNodes, document, oneOrMore);
+st(ExactlyOneDouble, xsDouble, exactlyOne);
+st(ExactlyOneDuration, xsDuration, exactlyOne);
+st(ExactlyOneElement, element, exactlyOne);
+st(ExactlyOneFloat, xsFloat, exactlyOne);
+st(ExactlyOneGDay, xsGDay, exactlyOne);
+st(ExactlyOneGMonthDay, xsGMonthDay, exactlyOne);
+st(ExactlyOneGMonth, xsGMonth, exactlyOne);
+st(ExactlyOneGYearMonth, xsGYearMonth, exactlyOne);
+st(ExactlyOneGYear, xsGYear, exactlyOne);
+st(ExactlyOneHexBinary, xsHexBinary, exactlyOne);
+st(ExactlyOneInteger, xsInteger, exactlyOne);
+st(ExactlyOneItem, item, exactlyOne);
+st(ExactlyOneNCName, xsNCName, exactlyOne);
+st(ExactlyOneNode, node, exactlyOne);
+st(ExactlyOneNumeric, numeric, exactlyOne);
+st(ExactlyOneProcessingInstruction, pi, exactlyOne);
+st(ExactlyOneQName, xsQName, exactlyOne);
+st(ExactlyOneString, xsString, exactlyOne);
+st(ExactlyOneTextNode, text, exactlyOne);
+st(ExactlyOneTime, xsTime, exactlyOne);
+st(ExactlyOneUntypedAtomic, xsUntypedAtomic, exactlyOne);
+st(ExactlyOneYearMonthDuration, xsYearMonthDuration, exactlyOne);
+st(OneOrMoreItems, item, oneOrMore);
+st(ZeroOrMoreAtomicTypes, xsAnyAtomicType, zeroOrMore);
+st(ZeroOrMoreElements, element, zeroOrMore);
+st(ZeroOrMoreIntegers, xsInteger, zeroOrMore);
+st(ZeroOrMoreItems, item, zeroOrMore);
+st(ZeroOrMoreNodes, node, zeroOrMore);
+st(ZeroOrMoreStrings, xsString, zeroOrMore);
+st(ZeroOrOneAnyURI, xsAnyURI, zeroOrOne);
+st(ZeroOrOneAtomicType, xsAnyAtomicType, zeroOrOne);
+st(ZeroOrOneBoolean, xsBoolean, zeroOrOne);
+st(ZeroOrOneDateTime, xsDateTime, zeroOrOne);
+st(ZeroOrOneDate, xsDate, zeroOrOne);
+st(ZeroOrOneDayTimeDuration, xsDayTimeDuration, zeroOrOne);
+st(ZeroOrOneDecimal, xsDecimal, zeroOrOne);
+st(ZeroOrOneDocumentNode, document, zeroOrOne);
+st(ZeroOrOneDuration, xsDuration, zeroOrOne);
+st(ZeroOrOneInteger, xsInteger, zeroOrOne);
+st(ZeroOrOneItem, item, zeroOrOne);
+st(ZeroOrOneNCName, xsNCName, zeroOrOne);
+st(ZeroOrOneNode, node, zeroOrOne);
+st(ZeroOrOneNumeric, numeric, zeroOrOne);
+st(ZeroOrOneQName, xsQName, zeroOrOne);
+st(ZeroOrOneString, xsString, zeroOrOne);
+st(ZeroOrOneTextNode, text, zeroOrOne);
+st(ZeroOrOneTime, xsTime, zeroOrOne);
+st(ZeroOrOneYearMonthDuration, xsYearMonthDuration, zeroOrOne);
+
+#undef st
+
+/* Special cases. */
+const EmptySequenceType::Ptr CommonSequenceTypes::Empty (new EmptySequenceType());
+const NoneType::Ptr CommonSequenceTypes::None (new NoneType());
+const SequenceType::Ptr CommonSequenceTypes::EBV (new EBVType());
+
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qcommonsequencetypes_p.h b/src/xmlpatterns/type/qcommonsequencetypes_p.h
new file mode 100644
index 0000000..52cfabb
--- /dev/null
+++ b/src/xmlpatterns/type/qcommonsequencetypes_p.h
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CommonSequenceTypes_H
+#define Patternist_CommonSequenceTypes_H
+
+#include "qemptysequencetype_p.h"
+#include "qnonetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides access to singleton instances of SequenceType sub-classes.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT CommonSequenceTypes
+ {
+ public:
+ /**
+ * <tt>xs:anyAtomicType?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneAtomicType;
+
+ /**
+ * <tt>xs:anyAtomicType</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneAtomicType;
+
+ /**
+ * <tt>xs:anyAtomicType*</tt>
+ */
+ static const SequenceType::Ptr ZeroOrMoreAtomicTypes;
+
+ /**
+ * <tt>item()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneItem;
+
+ /**
+ * <tt>item()*</tt>
+ */
+ static const SequenceType::Ptr ZeroOrMoreItems;
+
+ /**
+ * <tt>item()?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneItem;
+
+ /**
+ * <tt>item()+</tt>
+ */
+ static const SequenceType::Ptr OneOrMoreItems;
+
+ /**
+ * The empty sequence, <tt>empty-sequence()</tt>.
+ */
+ static const EmptySequenceType::Ptr Empty;
+
+ /**
+ * The special type @c none. Used for the function <tt>fn:error()</tt>, for example.
+ */
+ static const NoneType::Ptr None;
+
+ /**
+ * <tt>xs:anyURI</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneAnyURI;
+
+ /**
+ * <tt>xs:boolean</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneBoolean;
+
+ /**
+ * <tt>xs:boolean?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneBoolean;
+
+ /**
+ * <tt>xs:untypedAtomic</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneUntypedAtomic;
+
+ /**
+ * <tt>xs:integer</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneInteger;
+
+ /**
+ * <tt>xs:integer?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneInteger;
+
+ /**
+ * <tt>xs:decimal?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneDecimal;
+
+ /**
+ * <tt>xs:integer*</tt>
+ */
+ static const SequenceType::Ptr ZeroOrMoreIntegers;
+
+ /**
+ * <tt>xs:double</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneDouble;
+
+ /**
+ * <tt>xs:decimal</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneDecimal;
+
+ /**
+ * <tt>xs:float</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneFloat;
+
+ /**
+ * <tt>xs:QName</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneQName;
+
+ /**
+ * <tt>xs:string</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneString;
+
+ /**
+ * <tt>xs:string?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneString;
+
+ /**
+ * <tt>xs:string*</tt>
+ */
+ static const SequenceType::Ptr ZeroOrMoreStrings;
+
+ /**
+ * <tt>xs:NCName?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneNCName;
+
+ /**
+ * <tt>xs:NCName</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneNCName;
+
+ /**
+ * <tt>xs:QName?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneQName;
+
+ /**
+ * The artificial type in XPath 2.0 that covers @c xs:double, @c xs:float,
+ * @c xs:decimal, with cardinality zero or one.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#dt-numeric">XML Path Language
+ * (XPath) 2.0, definition for Numeric</a>
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 1.3 Function Signatures and Descriptions</a>
+ * @see BuiltinTypes::numeric
+ */
+ static const SequenceType::Ptr ZeroOrOneNumeric;
+
+ /**
+ * @c numeric
+ */
+ static const SequenceType::Ptr ExactlyOneNumeric;
+
+ /**
+ * <tt>node()?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneNode;
+
+ /**
+ * <tt>node()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneNode;
+
+ /**
+ * <tt>node()*</tt>
+ */
+ static const SequenceType::Ptr ZeroOrMoreNodes;
+
+ /**
+ * <tt>element()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneElement;
+
+ /**
+ * <tt>processing-instruction()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneProcessingInstruction;
+
+ /**
+ * <tt>attribute()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneAttribute;
+
+ /**
+ * <tt>text()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneTextNode;
+
+ /**
+ * <tt>text()?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneTextNode;
+
+ /**
+ * <tt>comment()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneComment;
+
+ /**
+ * <tt>element()*</tt>
+ */
+ static const SequenceType::Ptr ZeroOrMoreElements;
+
+ /**
+ * <tt>document-node()?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneDocumentNode;
+
+ /**
+ * <tt>document-node()</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneDocumentNode;
+
+ /**
+ * <tt>document-node()+</tt>
+ */
+ static const SequenceType::Ptr OneOrMoreDocumentNodes;
+
+ /**
+ * Identifiers all values which the Effective %Boolean Value
+ * can be extracted from.
+ */
+ static const SequenceType::Ptr EBV;
+
+ /**
+ * <tt>xs:anyURI?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneAnyURI;
+
+ /**
+ * <tt>xs:hexBinary</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneHexBinary;
+
+ /**
+ * <tt>xs:base64Binary</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneBase64Binary;
+
+ /**
+ * <tt>xs:date</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneDate;
+
+ /**
+ * <tt>xs:dateTime</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneDateTime;
+
+ /**
+ * <tt>xs:dayTimeDuration</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneDayTimeDuration;
+
+ /**
+ * <tt>xs:duration</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneDuration;
+
+ /**
+ * <tt>xs:gDay</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneGDay;
+
+ /**
+ * <tt>xs:gMonth</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneGMonth;
+
+ /**
+ * <tt>xs:gMonthDay</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneGMonthDay;
+
+ /**
+ * <tt>xs:gYear</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneGYear;
+
+ /**
+ * <tt>xs:gYearMonth</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneGYearMonth;
+
+ /**
+ * <tt>xs:yearMonthDuration</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneYearMonthDuration;
+
+ /**
+ * <tt>xs:time</tt>
+ */
+ static const SequenceType::Ptr ExactlyOneTime;
+
+ /**
+ * <tt>xs:time?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneDate;
+
+ /**
+ * <tt>xs:dateTime?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneDateTime;
+
+ /**
+ * <tt>xs:dayTimeDuration?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneDayTimeDuration;
+
+ /**
+ * <tt>xs:duration?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneDuration;
+
+ /**
+ * <tt>xs:time?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneTime;
+
+ /**
+ * <tt>xs:yearMonthDuration?</tt>
+ */
+ static const SequenceType::Ptr ZeroOrOneYearMonthDuration;
+
+ private:
+ /**
+ * The constructor is private and has no implementation,
+ * because this class is not meant to be instantiated.
+ *
+ * It should only be used via its static members.
+ */
+ inline CommonSequenceTypes();
+
+ Q_DISABLE_COPY(CommonSequenceTypes)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/type/qebvtype.cpp b/src/xmlpatterns/type/qebvtype.cpp
new file mode 100644
index 0000000..2e376d6
--- /dev/null
+++ b/src/xmlpatterns/type/qebvtype.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qitem_p.h"
+
+#include "qebvtype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+EBVType::EBVType()
+{
+}
+
+bool EBVType::itemMatches(const Item &item) const
+{
+ if(item.isNode())
+ return false;
+
+ return BuiltinTypes::xsBoolean->itemMatches(item) ||
+ BuiltinTypes::numeric->itemMatches(item) ||
+ BuiltinTypes::xsString->itemMatches(item) ||
+ BuiltinTypes::xsAnyURI->itemMatches(item) ||
+ CommonSequenceTypes::Empty->itemMatches(item) ||
+ BuiltinTypes::xsUntypedAtomic->itemMatches(item);
+}
+
+bool EBVType::xdtTypeMatches(const ItemType::Ptr &t) const
+{
+ return BuiltinTypes::node->xdtTypeMatches(t) ||
+ BuiltinTypes::xsBoolean->xdtTypeMatches(t) ||
+ BuiltinTypes::numeric->xdtTypeMatches(t) ||
+ BuiltinTypes::xsString->xdtTypeMatches(t) ||
+ BuiltinTypes::xsAnyURI->xdtTypeMatches(t) ||
+ *CommonSequenceTypes::Empty == *t ||
+ BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t) ||
+ /* Item & xs:anyAtomicType is ok, we do the checking at runtime. */
+ *BuiltinTypes::item == *t ||
+ *BuiltinTypes::xsAnyAtomicType == *t;
+}
+
+QString EBVType::displayName(const NamePool::Ptr &) const
+{
+ /* Some QName-lexical is not used here because it makes little sense
+ * for this strange type. Instead the operand type of the fn:boolean()'s
+ * argument is used. */
+ return QLatin1String("item()*(: EBV extractable type :)");
+}
+
+Cardinality EBVType::cardinality() const
+{
+ return Cardinality::zeroOrMore();
+}
+
+ItemType::Ptr EBVType::xdtSuperType() const
+{
+ return BuiltinTypes::item;
+}
+
+ItemType::Ptr EBVType::itemType() const
+{
+ return ItemType::Ptr(const_cast<EBVType *>(this));
+}
+
+bool EBVType::isAtomicType() const
+{
+ return false;
+}
+
+bool EBVType::isNodeType() const
+{
+ return true;
+}
+
+ItemType::Ptr EBVType::atomizedType() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "That this function is called makes no sense.");
+ return AtomicType::Ptr();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qebvtype_p.h b/src/xmlpatterns/type/qebvtype_p.h
new file mode 100644
index 0000000..4ae3301
--- /dev/null
+++ b/src/xmlpatterns/type/qebvtype_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_EBVType_H
+#define Patternist_EBVType_H
+
+#include "qatomictype_p.h"
+#include "qsequencetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents the type for which a value of can an Effective %Boolean Value
+ * be extracted from.
+ *
+ * EBVType is an artificial type. It is not available to users of any host language
+ * or is specified in any specification. It is used for implementing static type
+ * checking for expressions such as IfThenClause and AndExpression.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class EBVType : public ItemType,
+ public SequenceType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<EBVType> Ptr;
+
+ /**
+ * @todo docs if it's an ebvable type, etc.
+ */
+ virtual bool itemMatches(const Item &item) const;
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * @note The semantical meaning of this type's item type can
+ * surely be discussed. The function is provided due to
+ * it being mandated by the SequenceType base class.
+ *
+ * @returns always 'this' since EBVType is also an ItemType
+ */
+ virtual ItemType::Ptr itemType() const;
+
+ /**
+ * @note The semantical meaning of this type's cardinality
+ * can surely be discussed. The function is provided due to
+ * it being mandated by the SequenceType base class.
+ *
+ * @returns always Cardinality::zeroOrMore()
+ */
+ virtual Cardinality cardinality() const;
+
+ virtual bool isAtomicType() const;
+
+ /**
+ * @returns always @c null
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ /**
+ * @returns always BuiltinTypes::item
+ */
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isNodeType() const;
+
+ protected:
+ friend class CommonSequenceTypes;
+ EBVType();
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qemptysequencetype.cpp b/src/xmlpatterns/type/qemptysequencetype.cpp
new file mode 100644
index 0000000..205e99b
--- /dev/null
+++ b/src/xmlpatterns/type/qemptysequencetype.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "qemptysequencetype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+EmptySequenceType::EmptySequenceType()
+{
+}
+
+bool EmptySequenceType::xdtTypeMatches(const ItemType::Ptr &other) const
+{
+ return *other == *this ||
+ CommonSequenceTypes::None->xdtTypeMatches(other);
+}
+
+bool EmptySequenceType::itemMatches(const Item &) const
+{
+ return false;
+}
+
+QString EmptySequenceType::displayName(const NamePool::Ptr &) const
+{
+ return QLatin1String("empty-sequence()");
+}
+
+ItemType::Ptr EmptySequenceType::xdtSuperType() const
+{
+ return BuiltinTypes::item;
+}
+
+Cardinality EmptySequenceType::cardinality() const
+{
+ return Cardinality::empty();
+}
+
+ItemType::Ptr EmptySequenceType::itemType() const
+{
+ return ItemType::Ptr(const_cast<EmptySequenceType *>(this));
+}
+
+bool EmptySequenceType::isNodeType() const
+{
+ return false;
+}
+
+bool EmptySequenceType::isAtomicType() const
+{
+ return false;
+}
+
+ItemType::Ptr EmptySequenceType::atomizedType() const
+{
+ return BuiltinTypes::xsAnyAtomicType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qemptysequencetype_p.h b/src/xmlpatterns/type/qemptysequencetype_p.h
new file mode 100644
index 0000000..a3bf6bb
--- /dev/null
+++ b/src/xmlpatterns/type/qemptysequencetype_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_EmptySequenceType_H
+#define Patternist_EmptySequenceType_H
+
+#include "qatomictype_p.h"
+#include "qsequencetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents the <tt>empty-sequence()</tt> type.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class EmptySequenceType : public ItemType,
+ public SequenceType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<EmptySequenceType> Ptr;
+
+ /**
+ * Possibly surprisingly, this function also returns true for the @c none type.
+ *
+ * @returns @c true if @p other is NoneType or EmptySequenceType, otherwise @c false.
+ */
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool itemMatches(const Item &item) const;
+
+ /**
+ * @returns always "empty-sequence()"
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ virtual bool isNodeType() const;
+ virtual bool isAtomicType() const;
+
+ /**
+ * @return always Cardinality::empty()
+ */
+ virtual Cardinality cardinality() const;
+
+ /**
+ * @returns always 'this' since it is also an ItemType
+ */
+ virtual ItemType::Ptr itemType() const;
+
+ /**
+ * @returns always @c xs:anyAtomicType
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ protected:
+ friend class CommonSequenceTypes;
+ EmptySequenceType();
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qgenericsequencetype.cpp b/src/xmlpatterns/type/qgenericsequencetype.cpp
new file mode 100644
index 0000000..41b9aaa
--- /dev/null
+++ b/src/xmlpatterns/type/qgenericsequencetype.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+
+#include "qgenericsequencetype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GenericSequenceType::GenericSequenceType(const ItemType::Ptr &iType,
+ const Cardinality &card) : m_itemType(iType),
+ m_cardinality(card)
+{
+ Q_ASSERT(m_itemType);
+}
+
+QString GenericSequenceType::displayName(const NamePool::Ptr &np) const
+{
+ return m_itemType->displayName(np) + m_cardinality.displayName(Cardinality::ExcludeExplanation);
+}
+
+Cardinality GenericSequenceType::cardinality() const
+{
+ return m_cardinality;
+}
+
+ItemType::Ptr GenericSequenceType::itemType() const
+{
+ return m_itemType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qgenericsequencetype_p.h b/src/xmlpatterns/type/qgenericsequencetype_p.h
new file mode 100644
index 0000000..0f48cc9
--- /dev/null
+++ b/src/xmlpatterns/type/qgenericsequencetype_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GenericSequenceType_H
+#define Patternist_GenericSequenceType_H
+
+#include "qcommonsequencetypes_p.h"
+#include "qsequencetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @todo Documentation is missing.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GenericSequenceType : public SequenceType
+ {
+ public:
+ GenericSequenceType(const ItemType::Ptr &itemType, const Cardinality &card);
+
+ /**
+ * Generates a name for the sequence type for display purposes. The
+ * prefix used for the QName identifying the schema type is conventional.
+ * An example of a display name for a GenericSequenceType is "xs:integer?".
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ virtual Cardinality cardinality() const;
+
+ virtual ItemType::Ptr itemType() const;
+
+ private:
+ const ItemType::Ptr m_itemType;
+ const Cardinality m_cardinality;
+ };
+
+ /**
+ * @short An object generator for GenericSequenceType.
+ *
+ * makeGenericSequenceType() is a convenience function for avoiding invoking
+ * the @c new operator, and wrapping the result in GenericSequenceType::Ptr.
+ *
+ * @returns a smart pointer to to a GenericSequenceType instaniated from @p itemType and @p cardinality.
+ * @relates GenericSequenceType
+ */
+ static inline SequenceType::Ptr
+ makeGenericSequenceType(const ItemType::Ptr &itemType, const Cardinality &cardinality)
+ {
+ /* An empty sequence of say integers, is the empty-sequence(). */
+ if(cardinality.isEmpty())
+ return CommonSequenceTypes::Empty;
+ else
+ return SequenceType::Ptr(new GenericSequenceType(itemType, cardinality));
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qitemtype.cpp b/src/xmlpatterns/type/qitemtype.cpp
new file mode 100644
index 0000000..6252672
--- /dev/null
+++ b/src/xmlpatterns/type/qitemtype.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGlobal>
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qitemtype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ItemType::~ItemType()
+{
+}
+
+const ItemType &ItemType::operator|(const ItemType &other) const
+{
+ const ItemType *ca = this;
+
+ if(other == *CommonSequenceTypes::None)
+ return *ca;
+
+ if(*ca == *CommonSequenceTypes::Empty)
+ return other;
+ else if(other == *CommonSequenceTypes::Empty)
+ return *ca;
+
+ do
+ {
+ const ItemType *cb = &other;
+ do
+ {
+ if(*ca == *cb)
+ return *ca;
+
+ cb = cb->xdtSuperType().data();
+ }
+ while(cb);
+
+ ca = ca->xdtSuperType().data();
+ }
+ while(ca);
+
+ Q_ASSERT_X(false, Q_FUNC_INFO, "We should never reach this line.");
+ return *this;
+}
+
+ItemType::Category ItemType::itemTypeCategory() const
+{
+ return Other;
+}
+
+bool ItemType::operator==(const ItemType &other) const
+{
+ return this == &other;
+}
+
+ItemType::InstanceOf ItemType::instanceOf() const
+{
+ return ClassOther;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qitemtype_p.h b/src/xmlpatterns/type/qitemtype_p.h
new file mode 100644
index 0000000..f3e5285
--- /dev/null
+++ b/src/xmlpatterns/type/qitemtype_p.h
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_ItemType_H
+#define Patternist_ItemType_H
+
+#include <QSharedData>
+
+#include <QtXmlPatterns/private/qnamepool_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QList;
+
+namespace QPatternist
+{
+ class Item;
+
+ /**
+ * @short Base class for the XPath Data Model's type hierarchy.
+ *
+ * It can not be instantiated, but it's possible via ItemType's two subtypes:
+ * Nodes, represented by QXmlNodeModelIndex, and atom types, represented by AtomicType.
+ *
+ * ItemType tries to by its design stay close to the notation used in Formal Semantics.
+ * The operator|() is a good example, it allow typing code to be written
+ * similar to how inference rules in the specification are written.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ItemType : public virtual QSharedData
+ {
+ public:
+ /**
+ * A smart pointer wrapping ItemType instances.
+ */
+ typedef QExplicitlySharedDataPointer<ItemType> Ptr;
+ /**
+ * A list of ItemType instances, each wrapped in a smart pointer.
+ */
+ typedef QList<ItemType::Ptr> List;
+
+ virtual ~ItemType();
+
+ enum Category
+ {
+ NodeNameTest = 1,
+ Other = 2
+ };
+
+ /**
+ * Determines whether this ItemType is equal to @p other.
+ *
+ * Many types are represented by singleton instances. For example, there
+ * exists only one instance of IntegerType. This operator==() takes advantage
+ * of that and uses equalness of object addresses for determining semantic
+ * equalness. This function is as a result fast.
+ *
+ * However, it's overridden in some cases, such as for name tests, where
+ * it's not guaranteed that there exists two types.
+ *
+ * @returns @c true if this ItemType is equal to @p other, otherwise @c false.
+ */
+ virtual bool operator==(const ItemType &other) const;
+
+ /**
+ * @returns the result of operator==() negated.
+ */
+ inline bool operator!=(const ItemType &other) const;
+
+ /**
+ * @returns a string representing the type. Used for diagnostic purposes. For a
+ * type whose name is a QName, a lexical representation should be returned
+ * with the prefix being a conventional one. Examples of a display names
+ * are "item()" and "xs:nonPositiveInteger".
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const = 0;
+
+ /**
+ * @param item the item that is to be matched. This is guaranteed by the caller
+ * to never be @c null.
+ */
+ virtual bool itemMatches(const Item &item) const = 0;
+
+ /**
+ * @short Returns @c true if @p other matches this type. That is, if @p
+ * other is equal to this type or a subtype of this type.
+ *
+ * For instance this statements evaluates to @c true:
+ *
+ * @code
+ * BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(BuiltinTypes::xsString);
+ * @endcode
+ *
+ * but this evaluates to @c false:
+ *
+ * @code
+ * BuiltinTypes::attribute->xdtTypeMatches(BuiltinTypes::node);
+ * @endcode
+ *
+ * @param other the other ItemType that is to be matched. This is guaranteed by the caller
+ * to never be @c null.
+ */
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const = 0;
+
+ virtual bool isNodeType() const = 0;
+ virtual bool isAtomicType() const = 0;
+
+ /**
+ * Determines the type's parent type in the XPath Data Model hierarchy. For example,
+ * for the type xs:anyAtomicType, the super type in the XPath Data Model is item(), not
+ * xs:anySimpleType. SchemaType::xdtSuperType navigates the schema hierarchy.
+ *
+ * @see SchemaType::wxsSuperType()
+ * @returns the type's super type.
+ */
+ virtual ItemType::Ptr xdtSuperType() const = 0;
+
+ /**
+ * @todo docs mention union, give if-expression example.
+ *
+ * Determines the super type that is closest to this ItemType and @p other. That is,
+ * the parent type of them both. For example, for the type xs:integer and xs:string
+ * the parent type is xs:anyAtomicType. For xs:NOTATION and processing-instruction(), it
+ * is item(), to name another example.
+ *
+ * This function can be seen as the type function prime(Type), defined in Formal Semantics.
+ *
+ * This walks the XPath Data Model type hierarchy, not the W3C XML Schema hierarchy.
+ * @param other the item type 'this' object, should be compared with. Invoking xdtSuperType
+ * on 'this' object with @p other as argument yields the same result as invoking the
+ * function on @p other with 'this'
+ * as argument.
+ * @returns the parent type of 'this' and @p other
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/\#jd_prime">XQuery 1.0 and XPath 2.0
+ * Formal Semantics, Prime Types, type function prime(Type)</a>
+ */
+ virtual const ItemType &operator|(const ItemType &other) const;
+
+ /**
+ * Determines the atomic type that the resulting sequence after
+ * atomization of this node would be an instance of. For example, for document node,
+ * xs:untypedAtomic is returned. Phrased differently, the returned type is the
+ * type of the result of the typed-value accessor.
+ *
+ * If the type cannot be atomized, it returns @c null.
+ *
+ * This function is also defined on SchemaType, because some schema types can also be
+ * atomized.
+ *
+ * @see SchemaType::atomizedType()
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/\#dm-typed-value">XQuery 1.0
+ * and XPath 2.0 Data Model, 5.15 typed-value Accessor</a>
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#jd_data">XQuery 1.0
+ * and XPath 2.0 Formal Semantics, data on auxiliary judgment</a>
+ * @returns the atomic type that the resulting sequence
+ * when performing atomization is an instance of.
+ */
+ virtual ItemType::Ptr atomizedType() const = 0;
+
+ /**
+ * @returns always Other
+ */
+ virtual Category itemTypeCategory() const;
+
+ enum InstanceOf
+ {
+ ClassLocalNameTest,
+ ClassNamespaceNameTest,
+ ClassQNameTest,
+ ClassOther
+ };
+
+ /**
+ * Determines what class this ItemType is an instance of. This
+ * is in needed in some implementations of operator operator==(). By
+ * default, Other is returned.
+ */
+ virtual InstanceOf instanceOf() const;
+
+ inline ItemType()
+ {
+ }
+
+ private:
+ Q_DISABLE_COPY(ItemType)
+ };
+
+ /**
+ * This operator exists for making it easier to use the ItemType class, which
+ * always are wrapped in ItemType::Ptr, by taking care of the dereferencing
+ * of ItemType::Ptr instances. Semantically, it performs the same as
+ * ItemType's operator of the same name.
+ *
+ * @relates ItemType
+ * @see ItemType::operator|()
+ * @see operator|=(ItemType::Ptr &, const ItemType::Ptr &)
+ */
+ inline ItemType::Ptr operator|(const ItemType::Ptr &op1,
+ const ItemType::Ptr &op2)
+ {
+ return ItemType::Ptr(const_cast<ItemType *>(&(*op1 | *op2)));
+ }
+
+ bool ItemType::operator!=(const ItemType &other) const
+ {
+ return this != &other;
+ }
+
+ /**
+ * @short Computes the union type of @p op1 and @p op2, and assigns it to @p op1.
+ *
+ * This operator exists for making it easier to use the ItemType class, which
+ * always are wrapped in ItemType::Ptr, by taking care of the dereferencing
+ * of the ItemType::Ptr instances.
+ *
+ * @relates ItemType
+ * @see operator|(const ItemType::Ptr &, const ItemType::Ptr &)
+ * @param op1 if @c null, @p op2 is returned unchanged
+ * @param op2 the other operand
+ */
+ inline void operator|=(ItemType::Ptr &op1, const ItemType::Ptr &op2)
+ {
+ op1 = op1 | op2;
+ }
+
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::ItemType::Ptr, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qlocalnametest.cpp b/src/xmlpatterns/type/qlocalnametest.cpp
new file mode 100644
index 0000000..4c47476
--- /dev/null
+++ b/src/xmlpatterns/type/qlocalnametest.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+#include "qitem_p.h"
+#include "qxpathhelper_p.h"
+
+#include "qlocalnametest_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+LocalNameTest::LocalNameTest(const ItemType::Ptr &primaryType,
+ const QXmlName::LocalNameCode &ncName) : AbstractNodeTest(primaryType),
+ m_ncName(ncName)
+{
+}
+
+ItemType::Ptr LocalNameTest::create(const ItemType::Ptr &primaryType, const QXmlName::LocalNameCode localName)
+{
+ Q_ASSERT(primaryType);
+
+ return ItemType::Ptr(new LocalNameTest(primaryType, localName));
+}
+
+bool LocalNameTest::itemMatches(const Item &item) const
+{
+ Q_ASSERT(item.isNode());
+ return m_primaryType->itemMatches(item) &&
+ item.asNode().name().localName() == m_ncName;
+}
+
+QString LocalNameTest::displayName(const NamePool::Ptr &np) const
+{
+ QString displayOther(m_primaryType->displayName(np));
+
+ return displayOther.insert(displayOther.size() - 1,
+ QString::fromLatin1("*:") + np->stringForLocalName(m_ncName));
+}
+
+ItemType::InstanceOf LocalNameTest::instanceOf() const
+{
+ return ClassLocalNameTest;
+}
+
+bool LocalNameTest::operator==(const ItemType &other) const
+{
+ return other.instanceOf() == ClassLocalNameTest &&
+ static_cast<const LocalNameTest &>(other).m_ncName == m_ncName;
+}
+
+PatternPriority LocalNameTest::patternPriority() const
+{
+ return -0.25;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qlocalnametest_p.h b/src/xmlpatterns/type/qlocalnametest_p.h
new file mode 100644
index 0000000..dc54fcf
--- /dev/null
+++ b/src/xmlpatterns/type/qlocalnametest_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_LocalNameTest_H
+#define Patternist_LocalNameTest_H
+
+#include "qabstractnodetest_p.h"
+
+template<typename Key, typename Value> class QHash;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A name test that is of the type <tt>*:local-name</tt>.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class LocalNameTest : public AbstractNodeTest
+ {
+ public:
+ typedef QHash<QString, ItemType::Ptr> Hash;
+
+ static ItemType::Ptr create(const ItemType::Ptr &primaryType, const QXmlName::LocalNameCode localName);
+
+ /**
+ * @note This function assumes that @p item is a QXmlNodeModelIndex.
+ */
+ virtual bool itemMatches(const Item &item) const;
+
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ virtual bool operator==(const ItemType &other) const;
+ virtual PatternPriority patternPriority() const;
+
+ protected:
+ virtual InstanceOf instanceOf() const;
+
+ private:
+ LocalNameTest(const ItemType::Ptr &primaryType, const QXmlName::LocalNameCode &ncName);
+
+ const QXmlName::LocalNameCode m_ncName;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qmultiitemtype.cpp b/src/xmlpatterns/type/qmultiitemtype.cpp
new file mode 100644
index 0000000..49261f3
--- /dev/null
+++ b/src/xmlpatterns/type/qmultiitemtype.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+
+#include "qmultiitemtype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+MultiItemType::MultiItemType(const ItemType::List &list) : m_types(list),
+ m_end(list.constEnd())
+{
+ Q_ASSERT_X(list.count() >= 2, Q_FUNC_INFO,
+ "It makes no sense to use MultiItemType for types less than two.");
+ Q_ASSERT_X(list.count(ItemType::Ptr()) == 0, Q_FUNC_INFO,
+ "No member in the list can be null.");
+}
+
+QString MultiItemType::displayName(const NamePool::Ptr &np) const
+{
+ QString result;
+ ItemType::List::const_iterator it(m_types.constBegin());
+
+ while(true)
+ {
+ result += (*it)->displayName(np);
+ ++it;
+
+ if(it != m_end)
+ result += QLatin1String(" | ");
+ else
+ break;
+ }
+
+ return result;
+}
+
+bool MultiItemType::itemMatches(const Item &item) const
+{
+ for(ItemType::List::const_iterator it(m_types.constBegin()); it != m_end; ++it)
+ if((*it)->itemMatches(item))
+ return true;
+
+ return false;
+}
+
+bool MultiItemType::xdtTypeMatches(const ItemType::Ptr &type) const
+{
+ for(ItemType::List::const_iterator it(m_types.constBegin()); it != m_end; ++it)
+ if((*it)->xdtTypeMatches(type))
+ return true;
+
+ return false;
+}
+
+bool MultiItemType::isNodeType() const
+{
+ for(ItemType::List::const_iterator it(m_types.constBegin()); it != m_end; ++it)
+ if((*it)->isNodeType())
+ return true;
+
+ return false;
+}
+
+bool MultiItemType::isAtomicType() const
+{
+ for(ItemType::List::const_iterator it(m_types.constBegin()); it != m_end; ++it)
+ if((*it)->isAtomicType())
+ return true;
+
+ return false;
+}
+
+ItemType::Ptr MultiItemType::xdtSuperType() const
+{
+ ItemType::List::const_iterator it(m_types.constBegin());
+ /* Load the first one, and jump over it in the loop. */
+ ItemType::Ptr result((*it)->xdtSuperType());
+ ++it;
+
+ for(; it != m_end; ++it)
+ result |= (*it)->xdtSuperType();
+
+ return result;
+}
+
+ItemType::Ptr MultiItemType::atomizedType() const
+{
+ ItemType::List::const_iterator it(m_types.constBegin());
+ /* Load the first one, and jump over it in the loop. */
+ ItemType::Ptr result((*it)->atomizedType());
+ ++it;
+
+ for(; it != m_end; ++it)
+ result |= (*it)->atomizedType();
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qmultiitemtype_p.h b/src/xmlpatterns/type/qmultiitemtype_p.h
new file mode 100644
index 0000000..6069172
--- /dev/null
+++ b/src/xmlpatterns/type/qmultiitemtype_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_MultiItemType_H
+#define Patternist_MultiItemType_H
+
+#include <QList>
+
+#include "qitemtype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents multiple types such as <tt>document()</tt> @em or <tt>xs:integer</tt>.
+ *
+ * In some situations two or more different types are allowed. For example, XQuery's
+ * @c validate expression accepts document or element nodes(but not attribute
+ * nodes, for example). MultiItemType is useful in such situations, its constructor
+ * takes a list of ItemType instances which its member functions treats as a wholeness.
+ *
+ * For example, xdtTypeMatches() returns @c true if any of the represented types matches.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class MultiItemType : public ItemType
+ {
+ public:
+ /**
+ * Creates a MultiItemType representing the types in @p typeList. @p typeList must
+ * contain two or more types.
+ */
+ MultiItemType(const ItemType::List &typeList);
+
+ /**
+ * The display name are the names concatenated with "|" as separator. For example,
+ * if this MultiItemType represents the types <tt>document()</tt>, <tt>xs:integer</tt>,
+ * and <tt>xs:anyAtomicType</tt>, the display name is
+ * "document() | xs:integer | xs:anyAtomicType".
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * If any of the types this MultiItemType represents matches @p item, it is
+ * considered a match.
+ *
+ * @returns @c true if any of the housed ItemType instances matches @p item, otherwise @c false
+ */
+ virtual bool itemMatches(const Item &item) const;
+
+ /**
+ * If any of the types this MultiItemType represents matches @p other, it is
+ * considered a match.
+ *
+ * @returns @c true if any of the housed ItemType instances matches @p other, otherwise @c false
+ */
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+
+ /**
+ * @returns @c true if any of the represented types is a node type.
+ */
+ virtual bool isNodeType() const;
+
+ /**
+ * @returns @c true if any of the represented types is an atomic type.
+ */
+ virtual bool isAtomicType() const;
+
+ /**
+ * Determines the union type of all the represented types super types. For example,
+ * if the represented types are <tt>xs:integer</tt>, <tt>document()</tt>
+ * and <tt>xs:string</tt>, <tt>item()</tt> is returned.
+ */
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ /**
+ * Determines the union type of all the represented types atomized types. For example,
+ * if the represented types are <tt>xs:integer</tt> and <tt>document()</tt>,
+ * <tt>xs:anyAtomicType</tt> is returned, because that's the super type of <tt>xs:integer</tt>
+ * and <tt>xs:untypedAtomic</tt>.
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ private:
+ const ItemType::List m_types;
+ const ItemType::List::const_iterator m_end;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qnamedschemacomponent.cpp b/src/xmlpatterns/type/qnamedschemacomponent.cpp
new file mode 100644
index 0000000..0edd593
--- /dev/null
+++ b/src/xmlpatterns/type/qnamedschemacomponent.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnamedschemacomponent_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamedSchemaComponent::NamedSchemaComponent()
+{
+}
+
+NamedSchemaComponent::~NamedSchemaComponent()
+{
+}
+
+void NamedSchemaComponent::setName(const QXmlName &name)
+{
+ m_name = name;
+}
+
+QXmlName NamedSchemaComponent::name(const NamePool::Ptr&) const
+{
+ return m_name;
+}
+
+QString NamedSchemaComponent::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(m_name);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qnamedschemacomponent_p.h b/src/xmlpatterns/type/qnamedschemacomponent_p.h
new file mode 100644
index 0000000..2c8c6ce
--- /dev/null
+++ b/src/xmlpatterns/type/qnamedschemacomponent_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamedSchemaComponent_H
+#define Patternist_NamedSchemaComponent_H
+
+#include "qnamepool_p.h"
+#include "qschemacomponent_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all named components that can appear in a W3C XML Schema.
+ *
+ * @ingroup Patternist_types
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class NamedSchemaComponent : public SchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NamedSchemaComponent> Ptr;
+
+ /**
+ * Describes the blocking constraints that are given by the 'block' attributes.
+ */
+ enum BlockingConstraint
+ {
+ RestrictionConstraint = 1,
+ ExtensionConstraint = 2,
+ SubstitutionConstraint = 4
+ };
+ Q_DECLARE_FLAGS(BlockingConstraints, BlockingConstraint)
+
+ /**
+ * Creates a new named schema component.
+ */
+ NamedSchemaComponent();
+
+ /**
+ * Destroys the named schema component.
+ */
+ virtual ~NamedSchemaComponent();
+
+ /**
+ * Sets the @p name of the schema component.
+ */
+ void setName(const QXmlName &name);
+
+ /**
+ * Returns the name of the schema component.
+ *
+ * @param namePool The name pool the name belongs to.
+ */
+ virtual QXmlName name(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Returns the display name of the schema component.
+ *
+ * @param namePool The name pool the name belongs to.
+ */
+ virtual QString displayName(const NamePool::Ptr &namePool) const;
+
+ private:
+ QXmlName m_name;
+ };
+
+ Q_DECLARE_OPERATORS_FOR_FLAGS(NamedSchemaComponent::BlockingConstraints)
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qnamespacenametest.cpp b/src/xmlpatterns/type/qnamespacenametest.cpp
new file mode 100644
index 0000000..3975c87
--- /dev/null
+++ b/src/xmlpatterns/type/qnamespacenametest.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+#include "qitem_p.h"
+
+#include "qnamespacenametest_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamespaceNameTest::NamespaceNameTest(const ItemType::Ptr &primaryType,
+ const QXmlName::NamespaceCode namespaceURI) : AbstractNodeTest(primaryType),
+ m_namespaceURI(namespaceURI)
+{
+}
+
+ItemType::Ptr NamespaceNameTest::create(const ItemType::Ptr &primaryType, const QXmlName::NamespaceCode namespaceURI)
+{
+ Q_ASSERT(primaryType);
+
+ return ItemType::Ptr(new NamespaceNameTest(primaryType, namespaceURI));
+}
+
+bool NamespaceNameTest::itemMatches(const Item &item) const
+{
+ Q_ASSERT(item.isNode());
+ return m_primaryType->itemMatches(item) &&
+ item.asNode().name().namespaceURI() == m_namespaceURI;
+}
+
+QString NamespaceNameTest::displayName(const NamePool::Ptr &np) const
+{
+ return QLatin1Char('{') + np->stringForNamespace(m_namespaceURI) + QLatin1String("}:*");
+}
+
+ItemType::InstanceOf NamespaceNameTest::instanceOf() const
+{
+ return ClassNamespaceNameTest;
+}
+
+bool NamespaceNameTest::operator==(const ItemType &other) const
+{
+ return other.instanceOf() == ClassNamespaceNameTest &&
+ static_cast<const NamespaceNameTest &>(other).m_namespaceURI == m_namespaceURI;
+}
+
+PatternPriority NamespaceNameTest::patternPriority() const
+{
+ return -0.25;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qnamespacenametest_p.h b/src/xmlpatterns/type/qnamespacenametest_p.h
new file mode 100644
index 0000000..96724de
--- /dev/null
+++ b/src/xmlpatterns/type/qnamespacenametest_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamespaceNameTest_H
+#define Patternist_NamespaceNameTest_H
+
+#include "qabstractnodetest_p.h"
+
+template<typename Key, typename Value> class QHash;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A name test that is of the type <tt>prefix:*</tt>.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NamespaceNameTest : public AbstractNodeTest
+ {
+ public:
+ typedef QHash<QString, ItemType::Ptr> Hash;
+
+ static ItemType::Ptr create(const ItemType::Ptr &primaryType, const QXmlName::NamespaceCode namespaceURI);
+
+ /**
+ * @note This function assumes that @p item is a QXmlNodeModelIndex.
+ */
+ virtual bool itemMatches(const Item &item) const;
+
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ virtual bool operator==(const ItemType &other) const;
+ PatternPriority patternPriority() const;
+
+ protected:
+ virtual InstanceOf instanceOf() const;
+
+ private:
+ NamespaceNameTest(const ItemType::Ptr &primaryType, const QXmlName::NamespaceCode namespaceURI);
+ const QXmlName::NamespaceCode m_namespaceURI;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qnonetype.cpp b/src/xmlpatterns/type/qnonetype.cpp
new file mode 100644
index 0000000..0ec5a7b
--- /dev/null
+++ b/src/xmlpatterns/type/qnonetype.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qnonetype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NoneType::NoneType()
+{
+}
+
+bool NoneType::itemMatches(const Item &) const
+{
+ return false;
+}
+
+bool NoneType::xdtTypeMatches(const ItemType::Ptr &t) const
+{
+ return *this == *t;
+}
+
+const ItemType &NoneType::operator|(const ItemType &other) const
+{
+ return other;
+}
+
+QString NoneType::displayName(const NamePool::Ptr &) const
+{
+ return QLatin1String("none");
+}
+
+Cardinality NoneType::cardinality() const
+{
+ return Cardinality::zeroOrMore();
+}
+
+ItemType::Ptr NoneType::itemType() const
+{
+ return ItemType::Ptr(const_cast<NoneType *>(this));
+}
+
+bool NoneType::isAtomicType() const
+{
+ return false;
+}
+
+bool NoneType::isNodeType() const
+{
+ return false;
+}
+
+ItemType::Ptr NoneType::atomizedType() const
+{
+ return BuiltinTypes::xsAnyAtomicType;
+}
+
+ItemType::Ptr NoneType::xdtSuperType() const
+{
+ return BuiltinTypes::item;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qnonetype_p.h b/src/xmlpatterns/type/qnonetype_p.h
new file mode 100644
index 0000000..f68d27d
--- /dev/null
+++ b/src/xmlpatterns/type/qnonetype_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NoneType_H
+#define Patternist_NoneType_H
+
+#include "qatomictype_p.h"
+#include "qsequencetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents the special <tt>none</tt> type.
+ *
+ * @ingroup Patternist_types
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_content_models">XQuery 1.0 and
+ * XPath 2.0 Formal Semantics, 2.4.3 Content models</a>
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fnerror">XQuery 1.0 and XPath 2.0
+ * Formal Semantics, 7.2.9 The fn:error function</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NoneType : public ItemType,
+ public SequenceType
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NoneType> Ptr;
+
+ virtual bool itemMatches(const Item &item) const;
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+
+ /**
+ * @returns always "none". That is, no namespace prefix
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * @note The semantical meaning of this type's item type can
+ * surely be discussed. The function is provided due to
+ * it being mandated by the SequenceType base class.
+ *
+ * @returns always 'this' since NoneType is also an ItemType
+ */
+ virtual ItemType::Ptr itemType() const;
+
+ /**
+ * @note The semantical meaning of this type's cardinality
+ * can surely be discussed. The function is provided due to
+ * it being mandated by the SequenceType base class.
+ *
+ * @returns always Cardinality::zeroOrMore()
+ */
+ virtual Cardinality cardinality() const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isAtomicType() const;
+
+ /**
+ * This can be thought to be a weird function for this type(none). There
+ * is no atomized type for none, perhaps the best from a conceptual perspective
+ * would be to return @c null.
+ *
+ * This function returns BuiltinTypes::xsAnyAtomicType because
+ * the generic type checking code inserts an Atomizer in the AST
+ * when an error() function(or other node which has type none) is part of
+ * an operator expression(value/general comparison, arithmetics). The Atomizer
+ * returns the atomizedType() of its child, and by here returning xsAnyAtomicType,
+ * static operator lookup is postponed to runtime. Subsequently, expressions like error()
+ * works properly with other XPath expressions.
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isNodeType() const;
+
+ /**
+ * @returns always item()
+ */
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ /**
+ * @returns always @p other. The none type can be thought as
+ * disappearing when attempting to find the union of it and
+ * another type.
+ */
+ virtual const ItemType &operator|(const ItemType &other) const;
+
+ protected:
+
+ friend class CommonSequenceTypes;
+ NoneType();
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qnumerictype.cpp b/src/xmlpatterns/type/qnumerictype.cpp
new file mode 100644
index 0000000..bfcb6d0
--- /dev/null
+++ b/src/xmlpatterns/type/qnumerictype.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+#include "qschematype_p.h"
+
+#include "qnumerictype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NumericType::NumericType()
+{
+}
+
+NumericType::~NumericType()
+{
+}
+
+bool NumericType::itemMatches(const Item &item) const
+{
+ if(item.isNode())
+ return false;
+
+ return BuiltinTypes::xsDouble->itemMatches(item) ||
+ BuiltinTypes::xsDecimal->itemMatches(item) ||
+ BuiltinTypes::xsFloat->itemMatches(item);
+}
+
+bool NumericType::xdtTypeMatches(const ItemType::Ptr &t) const
+{
+ return BuiltinTypes::xsDouble->xdtTypeMatches(t) ||
+ BuiltinTypes::xsDecimal->xdtTypeMatches(t) ||
+ BuiltinTypes::xsFloat->xdtTypeMatches(t) ||
+ *t == *this; /* If it's NumericType */
+}
+
+QString NumericType::displayName(const NamePool::Ptr &) const
+{
+ return QLatin1String("numeric");
+}
+
+SchemaType::Ptr NumericType::wxsSuperType() const
+{
+ return BuiltinTypes::xsAnyAtomicType;
+}
+
+ItemType::Ptr NumericType::xdtSuperType() const
+{
+ return BuiltinTypes::xsAnyAtomicType;
+}
+
+bool NumericType::isAbstract() const
+{
+ return true;
+}
+
+bool NumericType::isNodeType() const
+{
+ return false;
+}
+
+bool NumericType::isAtomicType() const
+{
+ return true;
+}
+
+ItemType::Ptr NumericType::atomizedType() const
+{
+ return AtomicType::Ptr();
+}
+
+AtomicTypeVisitorResult::Ptr NumericType::accept(const AtomicTypeVisitor::Ptr &,
+ const SourceLocationReflection *const) const
+{
+ return AtomicTypeVisitorResult::Ptr();
+}
+
+AtomicTypeVisitorResult::Ptr NumericType::accept(const ParameterizedAtomicTypeVisitor::Ptr &,
+ const qint16,
+ const SourceLocationReflection *const) const
+{
+ return AtomicTypeVisitorResult::Ptr();
+}
+
+AtomicComparatorLocator::Ptr NumericType::comparatorLocator() const
+{
+ return AtomicComparatorLocator::Ptr();
+}
+
+AtomicMathematicianLocator::Ptr NumericType::mathematicianLocator() const
+{
+ return AtomicMathematicianLocator::Ptr();
+}
+
+AtomicCasterLocator::Ptr NumericType::casterLocator() const
+{
+ return AtomicCasterLocator::Ptr();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qnumerictype_p.h b/src/xmlpatterns/type/qnumerictype_p.h
new file mode 100644
index 0000000..69c683a
--- /dev/null
+++ b/src/xmlpatterns/type/qnumerictype_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NumericType_H
+#define Patternist_NumericType_H
+
+#include "qatomictype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents the internal and abstract type @c fs:numeric.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#dt-fs_numeric">XQuery 1.0
+ * and XPath 2.0 Formal Semantics, Definition: fs:numeric</a>
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NumericType : public AtomicType
+ {
+ public:
+ virtual ~NumericType();
+
+ virtual bool itemMatches(const Item &item) const;
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+
+ /**
+ * @returns always "numeric". That is, no namespace prefix
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * @returns always @c true
+ */
+ virtual bool isAbstract() const;
+
+ /**
+ * @returns always @c false
+ */
+ virtual bool isNodeType() const;
+
+ /**
+ * @returns always @c true
+ */
+ virtual bool isAtomicType() const;
+
+ /**
+ * @returns always xs:anyAtomicType
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * @returns always xs:anyAtomicType
+ */
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ /**
+ * @returns @c null. It makes no sense to atomize the abstract type @c fs:numeric.
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ /**
+ * NumericType cannot be visited. This function is only implemented
+ * to satisfy the abstract super class's interface.
+ *
+ * @returns always a @c null pointer
+ */
+ virtual AtomicTypeVisitorResult::Ptr accept(const AtomicTypeVisitor::Ptr &visitor,
+ const SourceLocationReflection *const) const;
+
+ /**
+ * NumericType cannot be visited. This function is only implemented
+ * to satisfy the abstract super class's interface.
+ *
+ * @returns always a @c null pointer
+ */
+ virtual AtomicTypeVisitorResult::Ptr accept(const ParameterizedAtomicTypeVisitor::Ptr &visitor,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+
+ /**
+ * The type @c fs:numeric is an abstract type which therefore
+ * cannot be involved in comparisons. Hence, this function returns
+ * @c null. This function is only implemented to satisfy the abstract
+ * super class's interface.
+ *
+ * @returns always a @c null pointer
+ */
+ virtual AtomicComparatorLocator::Ptr comparatorLocator() const;
+
+ /**
+ * The type @c fs:numeric is an abstract type which therefore
+ * cannot be involved in arithmetics. Hence, this function returns
+ * @c null. This function is only implemented to satisfy the abstract
+ * super class's interface.
+ *
+ * @returns always a @c null pointer
+ */
+ virtual AtomicMathematicianLocator::Ptr mathematicianLocator() const;
+
+
+ /**
+ * The type @c fs:numeric is an abstract type which therefore
+ * cannot be involved in casting. Hence, this function returns
+ * @c null. This function is only implemented to satisfy the abstract
+ * super class's interface.
+ *
+ * @returns always a @c null pointer
+ */
+ virtual AtomicCasterLocator::Ptr casterLocator() const;
+
+ protected:
+ friend class BuiltinTypes;
+ NumericType();
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qprimitives_p.h b/src/xmlpatterns/type/qprimitives_p.h
new file mode 100644
index 0000000..ebbebcc
--- /dev/null
+++ b/src/xmlpatterns/type/qprimitives_p.h
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Primitives_H
+#define Patternist_Primitives_H
+
+#include <QtGlobal>
+#include <QtCore/QHash>
+#include <QtCore/QUrl>
+
+/**
+ * @file
+ * @short Contains enumerators and typedefs applying
+ * for Patternist on a global scale, as well as central documentation.
+ */
+
+/**
+ * @short Contains Patternist, an XPath 2.0, XQuery 1.0 and XSL-T 2.0 implementation.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+/**
+ * @short The namespace for the internal API of QtXmlPatterns
+ * @internal
+ */
+namespace QPatternist
+{
+ /**
+ * @defgroup Patternist_cppWXSTypes C++ Primitives for W3C XML Schema Number Types
+ *
+ * The implementations of W3C XML Schema's(WXS) number types, more specifically
+ * their value spaces, must in the end be represented by primitive C++ types.
+ * In addition, there is an extensive range of functions and classes that in
+ * different ways deals with data that will end up as instances of the WXS
+ * types. For this reason, a set of typedefs for these primitives exists, that
+ * are used throughout the API. This ensures consistency, reduces the amount
+ * of conversions, and potentially precision loss in conversions.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+ /**
+ * This is the native C++ scalar type holding the value space
+ * for atomic values of type xs:double. Taking this type, xsDouble,
+ * as parameter, is the most efficient way to integrate with xs:double.
+ *
+ * @ingroup Patternist_cppWXSTypes
+ */
+ typedef qreal xsDouble;
+
+ /**
+ * This is the native C++ scalar type holding the value space
+ * for atomic values of type xs:float. Taking this type, xsFloat,
+ * as parameter, is the most efficient way to integrate with xs:float.
+ *
+ * @ingroup Patternist_cppWXSTypes
+ */
+ typedef xsDouble xsFloat;
+
+ /**
+ * This is the native C++ scalar type holding the value space
+ * for atomic values of type xs:decimal. Taking this type, xsDecimal,
+ * as parameter, is the most efficient way to integrate with xs:decimal.
+ *
+ * @ingroup Patternist_cppWXSTypes
+ */
+ typedef xsDouble xsDecimal;
+
+ /**
+ * This is the native C++ scalar type holding the value space
+ * for atomic values of type xs:integer. Taking this type, xsInteger,
+ * as parameter, is the most efficient way to integrate with xs:integer.
+ *
+ * @ingroup Patternist_cppWXSTypes
+ */
+ typedef qint64 xsInteger;
+
+ /**
+ * This is the native C++ scalar type holding the value space
+ * for atomic values of type xs:integer. Taking this type, xsInteger,
+ * as parameter, is the most efficient way to integrate with xs:integer.
+ *
+ * @ingroup Patternist_cppWXSTypes
+ */
+ typedef qint32 VariableSlotID;
+
+ typedef qint32 DayCountProperty;
+ typedef qint32 HourCountProperty;
+ typedef qint32 MinuteCountProperty;
+ typedef qint32 MonthCountProperty;
+ typedef qint32 SecondCountProperty;
+ typedef qint64 MSecondCountProperty;
+ typedef qint32 SecondProperty;
+ typedef qint32 YearProperty;
+ typedef qint8 DayProperty;
+ typedef qint8 HourProperty;
+ typedef qint8 MinuteProperty;
+ typedef qint8 MonthProperty;
+
+ /**
+ * Milliseconds. 1 equals 0.001 SecondProperty.
+ */
+ typedef qint16 MSecondProperty;
+
+ /**
+ * The hour property of a zone offset. For example, -13 in the
+ * zone offset "-13:08".
+ */
+ typedef qint8 ZOHourProperty;
+
+ /**
+ * The minute property of a zone offset. For example, -08 in the
+ * zone offset "-13:08".
+ */
+ typedef qint8 ZOMinuteProperty;
+
+ /**
+ * The full zone offset in minutes.
+ */
+ typedef qint32 ZOTotal;
+
+ typedef xsDouble PatternPriority;
+
+ /**
+ * Signifies the import precedence of a template. For instance, the first
+ * stylesheet module has 1, the first import 2, and so forth. Smaller means
+ * higher import precedence. 0 is reserved for builtin templates.
+ */
+ typedef int ImportPrecedence;
+
+ /**
+ * @short Similar to Qt::escape(), but also escapes apostrophes and quotes,
+ * such that the result is suitable as attribute content too.
+ *
+ * Since Qt::escape() is in QtGui, using it creates a dependency on that
+ * library. This function does not.
+ *
+ * The implementation resides in qpatternistlocale.cpp.
+ *
+ * @see Qt::escape()
+ */
+ QString Q_AUTOTEST_EXPORT escape(const QString &input);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qqnametest.cpp b/src/xmlpatterns/type/qqnametest.cpp
new file mode 100644
index 0000000..5acead6
--- /dev/null
+++ b/src/xmlpatterns/type/qqnametest.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "qbuiltintypes_p.h"
+#include "qitem_p.h"
+#include "qitem_p.h"
+
+#include "qqnametest_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QNameTest::QNameTest(const ItemType::Ptr &primaryType,
+ const QXmlName qName) : AbstractNodeTest(primaryType)
+ , m_qName(qName)
+{
+ Q_ASSERT(!qName.isNull());
+}
+
+ItemType::Ptr QNameTest::create(const ItemType::Ptr &primaryType, const QXmlName qName)
+{
+ Q_ASSERT(!qName.isNull());
+ Q_ASSERT(primaryType);
+
+ return ItemType::Ptr(new QNameTest(primaryType, qName));
+}
+
+bool QNameTest::itemMatches(const Item &item) const
+{
+ Q_ASSERT(item.isNode());
+ return m_primaryType->itemMatches(item) &&
+ item.asNode().name() == m_qName;
+}
+
+QString QNameTest::displayName(const NamePool::Ptr &np) const
+{
+ QString displayOther(m_primaryType->displayName(np));
+
+ return displayOther.insert(displayOther.size() - 1, np->displayName(m_qName));
+}
+
+ItemType::InstanceOf QNameTest::instanceOf() const
+{
+ return ClassQNameTest;
+}
+
+bool QNameTest::operator==(const ItemType &other) const
+{
+ return other.instanceOf() == ClassQNameTest &&
+ static_cast<const QNameTest &>(other).m_qName == m_qName;
+}
+
+PatternPriority QNameTest::patternPriority() const
+{
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qqnametest_p.h b/src/xmlpatterns/type/qqnametest_p.h
new file mode 100644
index 0000000..29639ed
--- /dev/null
+++ b/src/xmlpatterns/type/qqnametest_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_QNameTest_H
+#define Patternist_QNameTest_H
+
+#include "qabstractnodetest_p.h"
+
+template<typename Key, typename Value> class QHash;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A name test that is of the type <tt>prefix:ncName</tt>.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class QNameTest : public AbstractNodeTest
+ {
+ public:
+ typedef QHash<QString, QNameTest::Ptr> Hash;
+
+ static ItemType::Ptr create(const ItemType::Ptr &primaryType, const QXmlName qName);
+
+ /**
+ * @note This function assumes that @p item is a QXmlNodeModelIndex.
+ */
+ virtual bool itemMatches(const Item &item) const;
+
+ virtual QString displayName(const NamePool::Ptr &np) const;
+
+ virtual bool operator==(const ItemType &other) const;
+
+ virtual PatternPriority patternPriority() const;
+
+ protected:
+ virtual InstanceOf instanceOf() const;
+
+ private:
+ QNameTest(const ItemType::Ptr &primaryType, const QXmlName qName);
+
+ const QXmlName m_qName;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qschemacomponent.cpp b/src/xmlpatterns/type/qschemacomponent.cpp
new file mode 100644
index 0000000..4bd64b8
--- /dev/null
+++ b/src/xmlpatterns/type/qschemacomponent.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qschemacomponent_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SchemaComponent::SchemaComponent()
+{
+}
+
+SchemaComponent::~SchemaComponent()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qschemacomponent_p.h b/src/xmlpatterns/type/qschemacomponent_p.h
new file mode 100644
index 0000000..15567eb
--- /dev/null
+++ b/src/xmlpatterns/type/qschemacomponent_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SchemaComponent_H
+#define Patternist_SchemaComponent_H
+
+#include <QSharedData>
+#include <QtGlobal>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all constructs that can appear in a W3C XML Schema.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SchemaComponent : public virtual QSharedData
+ {
+ public:
+ SchemaComponent();
+ virtual ~SchemaComponent();
+
+ private:
+ Q_DISABLE_COPY(SchemaComponent)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qschematype.cpp b/src/xmlpatterns/type/qschematype.cpp
new file mode 100644
index 0000000..61e1b48
--- /dev/null
+++ b/src/xmlpatterns/type/qschematype.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qschematype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SchemaType::SchemaType()
+{
+}
+
+SchemaType::~SchemaType()
+{
+}
+
+bool SchemaType::isSimpleType() const
+{
+ switch(category())
+ {
+ /* Fallthrough */
+ case SimpleTypeAtomic:
+ case SimpleTypeList:
+ case SimpleTypeUnion:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool SchemaType::isComplexType() const
+{
+ return category() == ComplexType;
+}
+
+bool SchemaType::isDefinedBySchema() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qschematype_p.h b/src/xmlpatterns/type/qschematype_p.h
new file mode 100644
index 0000000..bd84ab0
--- /dev/null
+++ b/src/xmlpatterns/type/qschematype_p.h
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SchemaType_H
+#define Patternist_SchemaType_H
+
+#include "qnamepool_p.h"
+#include "qschemacomponent_p.h"
+#include "qxmlname.h"
+
+template<typename N, typename M> class QHash;
+template<typename N> class QList;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class AtomicType;
+
+ /**
+ * @short Base class for W3C XML Schema types.
+ *
+ * This is the base class of all data types in a W3C XML Schema.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SchemaType : public SchemaComponent
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<SchemaType> Ptr;
+ typedef QHash<QXmlName, SchemaType::Ptr> Hash;
+ typedef QList<SchemaType::Ptr> List;
+
+ /**
+ * Schema types are divided into different categories such as
+ * complex type, atomic imple type, union simple type, and so forth. This
+ * enumerator, which category() returns a value of, identifies what
+ * category the type belong to.
+ *
+ * @todo Add docs & links for the enums
+ */
+ enum TypeCategory
+ {
+ None = 0,
+ /**
+ * A simple atomic type. These are also sometimes
+ * referred to as primitive types. An example of this type is
+ * xs:string.
+ *
+ * Formally speaking, a simple type with variety atomic.
+ */
+ SimpleTypeAtomic,
+ SimpleTypeList,
+ SimpleTypeUnion,
+ ComplexType
+ };
+
+ enum DerivationMethod
+ {
+ DerivationRestriction = 1,
+ DerivationExtension = 2,
+ DerivationUnion = 4,
+ DerivationList = 8,
+ /**
+ * Used for <tt>xs:anyType</tt>.
+ */
+ NoDerivation = 16
+ };
+
+ /**
+ * Describes the derivation constraints that are given by the 'final' or 'block' attributes.
+ */
+ enum DerivationConstraint
+ {
+ RestrictionConstraint = 1,
+ ExtensionConstraint = 2,
+ ListConstraint = 4,
+ UnionConstraint = 8
+ };
+ Q_DECLARE_FLAGS(DerivationConstraints, DerivationConstraint)
+
+ SchemaType();
+ virtual ~SchemaType();
+
+ /**
+ * Determines how this SchemaType is derived from its super type.
+ *
+ * @note Despite that DerivationMethod is designed for being
+ * used for bitwise OR'd value, this function may only return one enum
+ * value. If the type does not derive from any type, which is the case of
+ * <tt>xs:anyType</tt>, this function returns NoDerivation.
+ *
+ * @see SchemaType::wxsSuperType()
+ * @see <a href="http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-DerivationMethods">Document
+ * Object Model (DOM) Level 3 Core Specification, Definition group DerivationMethods</a>
+ * @returns a DerivationMethod enumerator signifiying how
+ * this SchemaType is derived from its base type
+ */
+ virtual DerivationMethod derivationMethod() const = 0;
+
+ /**
+ * Determines what derivation constraints exists for the type.
+ */
+ virtual DerivationConstraints derivationConstraints() const = 0;
+
+ /**
+ * Determines whether the type is an abstract type.
+ *
+ * @note It is important a correct value is returned, since
+ * abstract types must not be instantiated.
+ */
+ virtual bool isAbstract() const = 0;
+
+ /**
+ * @short Returns the name of the type.
+ *
+ * The reason to why we take the name pool argument, is that the basic
+ * types, @c xs:anySimpleType and so on, are stored globally in
+ * BuiltinTypes and ComonSequenceTypes, and therefore cannot be tied to
+ * a certain name pool. Type instances that knows they always will be
+ * used with a certain name pool, can therefore ignore @p np and return
+ * a QXmlName instance stored as a member.
+ *
+ * If the type code was refactored to not be store globally and
+ * therefore by design would be tied to a name pool, this argument could
+ * be removed.
+ */
+ virtual QXmlName name(const NamePool::Ptr &np) const = 0;
+
+ /**
+ * @short Returns a suitable display name for this type.
+ *
+ * See name() for an explanation to why we take a NamePool as argument.
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const = 0;
+
+ /**
+ * @returns the W3C XML Schema base type that this type derives from. All types
+ * returns an instance, except for the xs:anyType since it
+ * is the very base type of all types, and it returns 0. Hence,
+ * one can walk the hierarchy of a schema type by recursively calling
+ * wxsSuperType, until zero is returned.
+ *
+ * This function walks the Schema hierarchy. Some simple types, the atomic types,
+ * is also part of the XPath Data Model hierarchy, and their super type in that
+ * hierarchy can be introspected with xdtSuperType().
+ *
+ * wxsSuperType() can be said to correspond to the {base type definition} property
+ * in the Post Schema Valid Infoset(PSVI).
+ *
+ * @see ItemType::xdtSuperType()
+ */
+ virtual SchemaType::Ptr wxsSuperType() const = 0;
+
+ /**
+ * @returns @c true if @p other is identical to 'this' schema type or if @p other
+ * is either directly or indirectly a base type of 'this'. Hence, calling
+ * AnyType::wxsTypeMatches() with @p other as argument returns @c true for all types,
+ * since all types have @c xs:anyType as super type.
+ */
+ virtual bool wxsTypeMatches(const SchemaType::Ptr &other) const = 0;
+
+ virtual TypeCategory category() const = 0;
+
+ /**
+ * Determines whether the type is a simple type, by introspecting
+ * the result of category().
+ *
+ * @note Do not re-implement this function, but instead override category()
+ * and let it return an appropriate value.
+ */
+ virtual bool isSimpleType() const;
+
+ /**
+ * Determines whether the type is a complex type, by introspecting
+ * the result of category().
+ *
+ * @note Do not re-implement this function, but instead override category()
+ * and let it return an appropriate value.
+ */
+ virtual bool isComplexType() const;
+
+ /**
+ * Returns whether the value has been defined by a schema (is not a built in type).
+ */
+ virtual bool isDefinedBySchema() const;
+ };
+
+ Q_DECLARE_OPERATORS_FOR_FLAGS(SchemaType::DerivationConstraints)
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qschematypefactory.cpp b/src/xmlpatterns/type/qschematypefactory.cpp
new file mode 100644
index 0000000..a138c59
--- /dev/null
+++ b/src/xmlpatterns/type/qschematypefactory.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qschematypefactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SchemaTypeFactory::SchemaTypeFactory()
+{
+}
+
+SchemaTypeFactory::~SchemaTypeFactory()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qschematypefactory_p.h b/src/xmlpatterns/type/qschematypefactory_p.h
new file mode 100644
index 0000000..b7e646f
--- /dev/null
+++ b/src/xmlpatterns/type/qschematypefactory_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SchemaTypeFactory_H
+#define Patternist_SchemaTypeFactory_H
+
+#include <QSharedData>
+
+#include "qreportcontext_p.h"
+#include "qitemtype_p.h"
+#include "qschematype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A factory creating schema types.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SchemaTypeFactory : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<SchemaTypeFactory> Ptr;
+
+ SchemaTypeFactory();
+ virtual ~SchemaTypeFactory();
+
+ /**
+ * @returns a schema type for name @p name. If no schema type exists for @p name, @c null
+ * is returned
+ */
+ virtual SchemaType::Ptr createSchemaType(const QXmlName name) const = 0;
+
+ /**
+ * @returns a dictionary containing the types this factory serves. The key
+ * is the type's QName in Clark name syntax.
+ */
+ virtual SchemaType::Hash types() const = 0;
+
+ private:
+ Q_DISABLE_COPY(SchemaTypeFactory)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qsequencetype.cpp b/src/xmlpatterns/type/qsequencetype.cpp
new file mode 100644
index 0000000..29d9bb6
--- /dev/null
+++ b/src/xmlpatterns/type/qsequencetype.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsequencetype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SequenceType::~SequenceType()
+{
+}
+
+bool SequenceType::matches(const SequenceType::Ptr other) const
+{
+ Q_ASSERT(other);
+
+ return itemType()->xdtTypeMatches(other->itemType()) &&
+ cardinality().isMatch(other->cardinality());
+}
+
+bool SequenceType::is(const SequenceType::Ptr &other) const
+{
+ return matches(other) && other->matches(Ptr(this));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qsequencetype_p.h b/src/xmlpatterns/type/qsequencetype_p.h
new file mode 100644
index 0000000..969e587
--- /dev/null
+++ b/src/xmlpatterns/type/qsequencetype_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_SequenceType_H
+#define Patternist_SequenceType_H
+
+template<typename T> class QList;
+
+#include <QSharedData>
+
+#include "qcardinality_p.h"
+#include "qitemtype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ItemType;
+
+ /**
+ * @short A SequenceType instance represents the type of a sequence of Item
+ * instances.
+ *
+ * It carries a Cardinality and ItemType, and is hence conceptually
+ * identical to the SequenceType EBNF construct.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-sequencetype-syntax">XML
+ * Path Language (XPath) 2.0, 2.5.3 SequenceType Syntax</a>
+ */
+ class SequenceType : public virtual QSharedData
+ {
+ public:
+ inline SequenceType()
+ {
+ }
+
+ /**
+ * A smart pointer wrapping SequenceType instances.
+ */
+ typedef QExplicitlySharedDataPointer<const SequenceType> Ptr;
+
+ /**
+ * A list of SequenceType instances, each wrapped in a smart pointer.
+ */
+ typedef QList<SequenceType::Ptr> List;
+
+ virtual ~SequenceType();
+
+ /**
+ * Generates a name for the sequence type for display purposes. The
+ * prefix used for the QName identifying the schema type is conventional.
+ * An example of a display name for a SequenceType is "xs:integer?".
+ */
+ virtual QString displayName(const NamePool::Ptr &np) const = 0;
+
+ virtual Cardinality cardinality() const = 0;
+
+ virtual ItemType::Ptr itemType() const = 0;
+
+ /**
+ * Determines whether @p other is identical to, or a sub-type
+ * of this SequenceType. For example, if this SequenceType is
+ * <tt>xs:anyAtomicType</tt>, @c false is returned if @p other is <tt>element()</tt>,
+ * but @c true if @p other is <tt>xs:string</tt>.
+ *
+ * The return values of cardinality() and itemType() used with ItemType::xdtTypeMatches
+ * and Cardinality::isWithinScope() is used for achieving this.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-sequencetype-matching">XQuery 1.0:
+ * An XML Query Language, 2.5.4 SequenceType Matching</a>
+ */
+ bool matches(const SequenceType::Ptr other) const;
+
+ bool is(const SequenceType::Ptr &other) const;
+ private:
+ Q_DISABLE_COPY(SequenceType)
+ };
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::SequenceType::Ptr, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qtypechecker.cpp b/src/xmlpatterns/type/qtypechecker.cpp
new file mode 100644
index 0000000..ffc947b
--- /dev/null
+++ b/src/xmlpatterns/type/qtypechecker.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qargumentconverter_p.h"
+#include "qatomictype_p.h"
+#include "qatomizer_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcardinalityverifier_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qfunctionfactory_p.h"
+#include "qitemverifier_p.h"
+#include "qpatternistlocale_p.h"
+#include "quntypedatomicconverter_p.h"
+
+#include "qtypechecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QString TypeChecker::wrongType(const NamePool::Ptr &np,
+ const ItemType::Ptr &reqType,
+ const ItemType::Ptr &opType)
+{
+ return QtXmlPatterns::tr("Required type is %1, but %2 was found.")
+ .arg(formatType(np, reqType), formatType(np, opType));
+}
+
+Expression::Ptr TypeChecker::applyFunctionConversion(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqType,
+ const StaticContext::Ptr &context,
+ const ReportContext::ErrorCode code,
+ const Options options)
+{
+ Q_ASSERT_X(!ReportContext::codeToString(code).isEmpty(), Q_FUNC_INFO,
+ "This test ensures 'code' exists, otherwise codeToString() would assert.");
+ Q_ASSERT(operand);
+ Q_ASSERT(reqType);
+ Q_ASSERT(context);
+
+ /* Do it in two steps: verify type, and then cardinality. */
+ const Expression::Ptr cardVerified(CardinalityVerifier::verifyCardinality(operand, reqType->cardinality(), context, code));
+ return verifyType(cardVerified, reqType, context, code, options);
+}
+
+bool TypeChecker::promotionPossible(const ItemType::Ptr &fromType,
+ const ItemType::Ptr &toType,
+ const StaticContext::Ptr &context)
+{
+ /* These types can be promoted to xs:string. xs:untypedAtomic should be
+ * cast when interpreting it formally, but implementing it as a promotion
+ * gives the same result(and is faster). */
+ if(*toType == *BuiltinTypes::xsString &&
+ (BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(fromType) ||
+ BuiltinTypes::xsAnyURI->xdtTypeMatches(fromType)))
+ return true;
+
+ if(*toType == *BuiltinTypes::xsDouble &&
+ BuiltinTypes::numeric->xdtTypeMatches(fromType))
+ {
+ /* Any numeric can be promoted to xs:double. */
+ return true;
+ }
+
+ /* xs:decimal/xs:integer can be promoted to xs:float. */
+ if(*toType == *BuiltinTypes::xsFloat && BuiltinTypes::xsDecimal->xdtTypeMatches(fromType))
+
+ {
+ context->warning(QtXmlPatterns::tr("Promoting %1 to %2 may cause loss of precision.")
+ .arg(formatType(context->namePool(), fromType))
+ .arg(formatType(context->namePool(), BuiltinTypes::xsFloat)));
+ return true;
+ }
+
+ return false;
+}
+
+Expression::Ptr TypeChecker::typeCheck(Expression *const op,
+ const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ return Expression::Ptr(op->typeCheck(context, reqType));
+}
+
+Expression::Ptr TypeChecker::verifyType(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqSeqType,
+ const StaticContext::Ptr &context,
+ const ReportContext::ErrorCode code,
+ const Options options)
+{
+ const ItemType::Ptr reqType(reqSeqType->itemType());
+ const Expression::Properties props(operand->properties());
+
+ /* If operand requires a focus, do the necessary type checking for that. */
+ if(props.testFlag(Expression::RequiresFocus) && options.testFlag(CheckFocus))
+ {
+ const ItemType::Ptr contextType(context->contextItemType());
+ if(contextType)
+ {
+ if(props.testFlag(Expression::RequiresContextItem))
+ {
+ Q_ASSERT_X(operand->expectedContextItemType(), Q_FUNC_INFO,
+ "When the Expression sets the RequiresContextItem property, it must "
+ "return a type in expectedContextItemType()");
+ const ItemType::Ptr expectedContextType(operand->expectedContextItemType());
+
+ /* Allow the empty sequence. We don't want to trigger XPTY0020 on ()/... . */
+ if(!expectedContextType->xdtTypeMatches(contextType) && contextType != CommonSequenceTypes::Empty)
+ {
+ context->error(wrongType(context->namePool(), operand->expectedContextItemType(), contextType),
+ ReportContext::XPTY0020, operand.data());
+ return operand;
+ }
+ }
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("The focus is undefined."), ReportContext::XPDY0002, operand.data());
+ return operand;
+ }
+ }
+
+ SequenceType::Ptr operandSeqType(operand->staticType());
+ ItemType::Ptr operandType(operandSeqType->itemType());
+
+ /* This returns the operand if the types are identical or if operandType
+ * is a subtype of reqType. */
+ if(reqType->xdtTypeMatches(operandType) || *operandType == *CommonSequenceTypes::Empty)
+ return operand;
+
+ /* Since we haven't exited yet, it means that the operandType is a super type
+ * of reqType, and that there hence is a path down to it through the
+ * type hierachy -- but that doesn't necessarily mean that a up-cast(down the
+ * hierarchy) would succeed. */
+
+ Expression::Ptr result(operand);
+
+ if(reqType->isAtomicType())
+ {
+ const Expression::ID opID = operand->id();
+ if((opID == Expression::IDArgumentReference ||
+ (opID == Expression::IDCardinalityVerifier && operand->operands().first()->is(Expression::IDArgumentReference)))
+ && *BuiltinTypes::item == *operandType)
+ return Expression::Ptr(new ArgumentConverter(result, reqType));
+
+ if(!operandType->isAtomicType())
+ {
+ result = Expression::Ptr(new Atomizer(result));
+ /* The atomizer might know more about the type. */
+ operandType = result->staticType()->itemType();
+ }
+
+ if(reqType->xdtTypeMatches(operandType))
+ {
+ /* Atomization was sufficient. Either the expected type is xs:anyAtomicType
+ * or the type the Atomizer knows it returns, matches the required type. */
+ return result;
+ }
+
+ const bool compatModeEnabled = context->compatModeEnabled();
+
+ if((options.testFlag(AutomaticallyConvert) && BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(operandType)) ||
+ (compatModeEnabled && BuiltinTypes::xsString->xdtTypeMatches(reqType)))
+ {
+ if(*reqType == *BuiltinTypes::numeric)
+ {
+ result = typeCheck(new UntypedAtomicConverter(result, BuiltinTypes::xsDouble, code),
+ context, reqSeqType);
+ }
+ else
+ result = typeCheck(new UntypedAtomicConverter(result, reqType, code), context, reqSeqType);
+
+ /* The UntypedAtomicConverter might know more about the type, so reload. */
+ operandType = result->staticType()->itemType();
+ }
+ else if(compatModeEnabled && *reqType == *BuiltinTypes::xsDouble)
+ {
+ const FunctionFactory::Ptr functions(context->functionSignatures());
+ Expression::List numberArgs;
+ numberArgs.append(operand);
+
+ result = functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::number),
+ numberArgs,
+ context,
+ operand.data())->typeCheck(context, reqSeqType);
+ operandType = result->staticType()->itemType();
+ context->wrapExpressionWith(operand.data(), result);
+ }
+
+ if(reqType->xdtTypeMatches(operandType))
+ return result;
+
+ /* Test if promotion will solve it; the xdtTypeMatches didn't
+ * do that. */
+ if(options.testFlag(AutomaticallyConvert) && promotionPossible(operandType, reqType, context))
+ {
+ if(options.testFlag(GeneratePromotion))
+ return Expression::Ptr(new UntypedAtomicConverter(result, reqType));
+ else
+ return result;
+ }
+
+ if(operandType->xdtTypeMatches(reqType))
+ {
+ /* For example, operandType is numeric, and reqType is xs:integer. */
+ return Expression::Ptr(new ItemVerifier(result, reqType, code));
+ }
+ else
+ {
+ context->error(wrongType(context->namePool(), reqType, operandType), code, operand.data());
+ return result;
+ }
+ }
+ else if(reqType->isNodeType())
+ {
+
+ ReportContext::ErrorCode myCode;
+
+ if(*reqType == *CommonSequenceTypes::EBV->itemType())
+ myCode = ReportContext::FORG0006;
+ else
+ myCode = code;
+
+ /* empty-sequence() is considered valid because it's ok to do
+ * for example nilled( () ). That is, to pass an empty sequence to a
+ * function requiring for example node()?. */
+ if(*operandType == *CommonSequenceTypes::Empty)
+ return result;
+ else if(!operandType->xdtTypeMatches(reqType))
+ {
+ context->error(wrongType(context->namePool(), reqType, operandType), myCode, operand.data());
+ return result;
+ }
+
+ /* Operand must be an item. Thus, the sequence can contain both
+ * nodes and atomic values: we have to verify. */
+ return Expression::Ptr(new ItemVerifier(result, reqType, myCode));
+ }
+ else
+ {
+ Q_ASSERT(*reqType == *CommonSequenceTypes::Empty);
+
+ /* element() doesn't match empty-sequence(), but element()* does. */
+ if(!reqType->xdtTypeMatches(operandType) &&
+ !operandSeqType->cardinality().allowsEmpty())
+ {
+ context->error(wrongType(context->namePool(), reqType, operandType),
+ code, operand.data());
+ return result;
+ }
+ }
+
+ /* This line should be reached if required type is
+ * EBVType, and the operand is compatible. */
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qtypechecker_p.h b/src/xmlpatterns/type/qtypechecker_p.h
new file mode 100644
index 0000000..7dd1f5f
--- /dev/null
+++ b/src/xmlpatterns/type/qtypechecker_p.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_TypeChecker_H
+#define Patternist_TypeChecker_H
+
+#include "qstaticcontext_p.h"
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains functions that applies Function Conversion Rules and other
+ * kinds of compile-time type checking tasks.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class TypeChecker
+ {
+ public:
+ enum Option
+ {
+ /**
+ * @short When set, the function conversion rules are applied.
+ *
+ * For instance, this is type promotion and conversions from @c
+ * xs:untypedAtomic to @c xs:date. This is done for function calls,
+ * but not when binding an expression to a variable.
+ */
+ AutomaticallyConvert = 1,
+
+ /**
+ * @short Whether the focus should be checked or not.
+ *
+ * Sometimes the focus is unknown at the time
+ * applyFunctionConversion() is called, and therefore it is
+ * of interest to post pone the check to later on.
+ */
+ CheckFocus = 2,
+
+ /**
+ * When applyFunctionConversion() is passed AutomaticallyConvert
+ * and promotion is required, such as from @c xs:integer to
+ * @c xs:float, there will be no conversion performed, with the
+ * assumption that the receiver will call Numeric::toFloat() or
+ * similar.
+ *
+ * However, when GeneratePromotion is set, code will be generated
+ * that performs this conversion regardless of what any receiver
+ * do.
+ *
+ * This is useful in the case where one Expression only pipes the
+ * result of another. The only known case of that as of this
+ * writing is when UserFunctionCallsite evaluates its body.
+ */
+ GeneratePromotion
+ };
+ typedef QFlags<Option> Options;
+
+ /**
+ * @short Builds a pipeline of artificial AST nodes that ensures @p operand
+ * conforms to the type @p reqType by applying the Function
+ * Conversion Rules.
+ *
+ * This new Expression is returned, or, if no conversions were necessary,
+ * @p operand as it is.
+ *
+ * applyFunctionConversion() also performs various checks, such as if
+ * @p operand needs the focus and that the focus is defined in the
+ * @p context. These checks are largely guided by @p operand's
+ * Expression::properties().
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/\#id-function-calls">XML Path
+ * Language (XPath) 2.0, 3.1.5 Function Calls</a>, more specifically the
+ * Function Conversion Rules
+ */
+ static Expression::Ptr
+ applyFunctionConversion(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqType,
+ const StaticContext::Ptr &context,
+ const ReportContext::ErrorCode code = ReportContext::XPTY0004,
+ const Options = Options(AutomaticallyConvert | CheckFocus));
+ private:
+
+ static inline Expression::Ptr typeCheck(Expression *const op,
+ const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ /**
+ * @short Implements the type checking and promotion part of the Function Conversion Rules.
+ */
+ static Expression::Ptr verifyType(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqSeqType,
+ const StaticContext::Ptr &context,
+ const ReportContext::ErrorCode code,
+ const Options options);
+
+ /**
+ * Determines whether type promotion is possible from one type to another. False
+ * is returned when a promotion is not possible or if a promotion is not needed(as when
+ * the types are identical), since that can be considered to not be type promotion.
+ *
+ * @returns @c true if @p fromType can be promoted to @p toType.
+ * @see <a href="http://www.w3.org/TR/xpath20/#promotion">XML Path Language
+ * (XPath) 2.0, B.1 Type Promotion</a>
+ */
+ static bool promotionPossible(const ItemType::Ptr &fromType,
+ const ItemType::Ptr &toType,
+ const StaticContext::Ptr &context);
+
+ /**
+ * @short Centralizes a message-string to reduce work for translators
+ * and increase consistency.
+ */
+ static inline QString wrongType(const NamePool::Ptr &np,
+ const ItemType::Ptr &reqType,
+ const ItemType::Ptr &opType);
+
+ /**
+ * No implementation is provided for this constructor. This class
+ * is not supposed to be instantiated.
+ */
+ inline TypeChecker();
+
+ Q_DISABLE_COPY(TypeChecker)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/quntyped.cpp b/src/xmlpatterns/type/quntyped.cpp
new file mode 100644
index 0000000..234b3a9
--- /dev/null
+++ b/src/xmlpatterns/type/quntyped.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "quntyped_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Untyped::Untyped()
+{
+}
+
+SchemaType::Ptr Untyped::wxsSuperType() const
+{
+ return BuiltinTypes::xsAnyType;
+}
+
+QXmlName Untyped::name(const NamePool::Ptr &np) const
+{
+ return np->allocateQName(StandardNamespaces::xs, QLatin1String("untyped"));
+}
+
+ItemType::Ptr Untyped::atomizedType() const
+{
+ return BuiltinTypes::xsUntypedAtomic;
+}
+
+SchemaType::TypeCategory Untyped::category() const
+{
+ return SchemaType::ComplexType;
+}
+
+SchemaType::DerivationMethod Untyped::derivationMethod() const
+{
+ return NoDerivation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/quntyped_p.h b/src/xmlpatterns/type/quntyped_p.h
new file mode 100644
index 0000000..3056050
--- /dev/null
+++ b/src/xmlpatterns/type/quntyped_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Untyped_H
+#define Patternist_Untyped_H
+
+#include "qanytype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class AtomicType;
+
+ /**
+ * @short Represents the complex W3C XML Schema type <tt>xs:untyped</tt>.
+ *
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel/#types-predefined">XQuery 1.0 and XPath 2.0
+ * Data Model, 2.6.2 Predefined Types</a>
+ */
+ class Untyped : public AnyType
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<Untyped> Ptr;
+
+ /**
+ * @returns always BuiltinTypes::xsAnyType.
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ virtual QXmlName name(const NamePool::Ptr &np) const;
+
+ /**
+ * @returns always <tt>xs:untypedAtomic</tt>
+ */
+ virtual ItemType::Ptr atomizedType() const;
+
+ /**
+ * @returns always SchemaType::ComplexType
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * @returns always NoDerivation
+ */
+ virtual DerivationMethod derivationMethod() const;
+
+ protected:
+ friend class BuiltinTypes;
+
+ Untyped();
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/qxsltnodetest.cpp b/src/xmlpatterns/type/qxsltnodetest.cpp
new file mode 100644
index 0000000..0ae33e4
--- /dev/null
+++ b/src/xmlpatterns/type/qxsltnodetest.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qxsltnodetest_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XSLTNodeTest::xdtTypeMatches(const ItemType::Ptr &other) const
+{
+ if(!other->isNodeType())
+ return false;
+
+ return *static_cast<const XSLTNodeTest *>(other.data()) == *this
+ ? true
+ : xdtTypeMatches(other->xdtSuperType());
+}
+
+bool XSLTNodeTest::itemMatches(const Item &item) const
+{
+ Q_ASSERT(item);
+
+ return item.isNode() &&
+ item.asNode().kind() != QXmlNodeModelIndex::Document;
+}
+
+ItemType::Ptr XSLTNodeTest::xdtSuperType() const
+{
+ return BuiltinTypes::node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qxsltnodetest_p.h b/src/xmlpatterns/type/qxsltnodetest_p.h
new file mode 100644
index 0000000..a3f9204
--- /dev/null
+++ b/src/xmlpatterns/type/qxsltnodetest_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XSLTNodeTest_H
+#define Patternist_XSLTNodeTest_H
+
+#include "qanynodetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents @c node() in patterns in XSL-T, which
+ * are just like how @c node() usually is, except that it doesn't
+ * match document nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#pattern-semantics">XSL
+ * Transformations (XSLT) Version 2.0, 5.5.3 The Meaning of a Pattern</a>
+ * @ingroup Patternist_types
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @since 4.5
+ */
+ class XSLTNodeTest : public AnyNodeType
+ {
+ public:
+ virtual bool xdtTypeMatches(const ItemType::Ptr &other) const;
+ virtual bool itemMatches(const Item &item) const;
+
+ virtual ItemType::Ptr xdtSuperType() const;
+
+ protected:
+ friend class BuiltinTypes;
+
+ /**
+ * This constructor does nothing, but exists in order to make it impossible to
+ * instantiate this class from anywhere but from BuiltinTypes.
+ */
+ inline XSLTNodeTest()
+ {
+ }
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/type/type.pri b/src/xmlpatterns/type/type.pri
new file mode 100644
index 0000000..5425298
--- /dev/null
+++ b/src/xmlpatterns/type/type.pri
@@ -0,0 +1,72 @@
+HEADERS += $$PWD/qabstractnodetest_p.h \
+ $$PWD/qanyitemtype_p.h \
+ $$PWD/qanynodetype_p.h \
+ $$PWD/qanysimpletype_p.h \
+ $$PWD/qanytype_p.h \
+ $$PWD/qatomiccasterlocator_p.h \
+ $$PWD/qatomiccasterlocators_p.h \
+ $$PWD/qatomiccomparatorlocator_p.h \
+ $$PWD/qatomiccomparatorlocators_p.h \
+ $$PWD/qatomicmathematicianlocator_p.h \
+ $$PWD/qatomicmathematicianlocators_p.h \
+ $$PWD/qatomictypedispatch_p.h \
+ $$PWD/qatomictype_p.h \
+ $$PWD/qbasictypesfactory_p.h \
+ $$PWD/qbuiltinatomictype_p.h \
+ $$PWD/qbuiltinatomictypes_p.h \
+ $$PWD/qbuiltinnodetype_p.h \
+ $$PWD/qbuiltintypes_p.h \
+ $$PWD/qcardinality_p.h \
+ $$PWD/qcommonsequencetypes_p.h \
+ $$PWD/qebvtype_p.h \
+ $$PWD/qemptysequencetype_p.h \
+ $$PWD/qgenericsequencetype_p.h \
+ $$PWD/qitemtype_p.h \
+ $$PWD/qlocalnametest_p.h \
+ $$PWD/qmultiitemtype_p.h \
+ $$PWD/qnamedschemacomponent_p.h \
+ $$PWD/qnamespacenametest_p.h \
+ $$PWD/qnonetype_p.h \
+ $$PWD/qnumerictype_p.h \
+ $$PWD/qprimitives_p.h \
+ $$PWD/qqnametest_p.h \
+ $$PWD/qschemacomponent_p.h \
+ $$PWD/qschematypefactory_p.h \
+ $$PWD/qschematype_p.h \
+ $$PWD/qsequencetype_p.h \
+ $$PWD/qtypechecker_p.h \
+ $$PWD/quntyped_p.h \
+ $$PWD/qxsltnodetest_p.h
+
+SOURCES += $$PWD/qabstractnodetest.cpp \
+ $$PWD/qanyitemtype.cpp \
+ $$PWD/qanynodetype.cpp \
+ $$PWD/qanysimpletype.cpp \
+ $$PWD/qanytype.cpp \
+ $$PWD/qatomiccasterlocator.cpp \
+ $$PWD/qatomiccomparatorlocator.cpp \
+ $$PWD/qatomicmathematicianlocator.cpp \
+ $$PWD/qatomictype.cpp \
+ $$PWD/qbasictypesfactory.cpp \
+ $$PWD/qbuiltinatomictype.cpp \
+ $$PWD/qbuiltinatomictypes.cpp \
+ $$PWD/qcardinality.cpp \
+ $$PWD/qcommonsequencetypes.cpp \
+ $$PWD/qebvtype.cpp \
+ $$PWD/qemptysequencetype.cpp \
+ $$PWD/qgenericsequencetype.cpp \
+ $$PWD/qitemtype.cpp \
+ $$PWD/qlocalnametest.cpp \
+ $$PWD/qmultiitemtype.cpp \
+ $$PWD/qnamedschemacomponent.cpp \
+ $$PWD/qnamespacenametest.cpp \
+ $$PWD/qnonetype.cpp \
+ $$PWD/qnumerictype.cpp \
+ $$PWD/qqnametest.cpp \
+ $$PWD/qschemacomponent.cpp \
+ $$PWD/qschematype.cpp \
+ $$PWD/qschematypefactory.cpp \
+ $$PWD/qsequencetype.cpp \
+ $$PWD/qtypechecker.cpp \
+ $$PWD/quntyped.cpp \
+ $$PWD/qxsltnodetest.cpp
diff --git a/src/xmlpatterns/utils/qautoptr.cpp b/src/xmlpatterns/utils/qautoptr.cpp
new file mode 100644
index 0000000..56c3137
--- /dev/null
+++ b/src/xmlpatterns/utils/qautoptr.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QPatternist::AutoPtr
+ \brief A smart pointer very similar to std::auto_ptr.
+ \internal
+ \since 4.4
+ */
+
diff --git a/src/xmlpatterns/utils/qautoptr_p.h b/src/xmlpatterns/utils/qautoptr_p.h
new file mode 100644
index 0000000..b9fe6ec
--- /dev/null
+++ b/src/xmlpatterns/utils/qautoptr_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 QPatternist_AutoPtr_p_h
+#define QPatternist_AutoPtr_p_h
+
+#include <QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ template<typename T>
+ class AutoPtrRef
+ {
+ public:
+ explicit AutoPtrRef(T *const other) : m_ptr(other)
+ {
+ }
+
+ T* m_ptr;
+ };
+
+ template<typename T>
+ class AutoPtr
+ {
+ public:
+ explicit inline AutoPtr(T *pointer = 0) : m_ptr(pointer)
+ {
+ }
+
+ inline AutoPtr(AutoPtr<T> &other) : m_ptr(other.release())
+ {
+ }
+
+ inline ~AutoPtr()
+ {
+ delete m_ptr;
+ }
+
+ inline T &operator*() const
+ {
+ Q_ASSERT_X(m_ptr, Q_FUNC_INFO, "");
+ return *m_ptr;
+ }
+
+ T *operator->() const
+ {
+ Q_ASSERT_X(m_ptr, Q_FUNC_INFO, "");
+ return m_ptr;
+ }
+
+ inline bool operator!() const
+ {
+ return !m_ptr;
+ }
+
+ inline operator bool() const
+ {
+ return m_ptr != 0;
+ }
+
+ AutoPtr(AutoPtrRef<T> ref) : m_ptr(ref.m_ptr)
+ {
+ }
+
+ AutoPtr& operator=(AutoPtrRef<T> ref)
+ {
+ if(ref.m_ptr != m_ptr)
+ {
+ delete m_ptr;
+ m_ptr = ref.m_ptr;
+ }
+ return *this;
+ }
+
+ template<typename L>
+ operator AutoPtrRef<L>()
+ {
+ return AutoPtrRef<L>(this->release());
+ }
+
+ template<typename L>
+ operator AutoPtr<L>()
+ {
+ return AutoPtr<L>(this->release());
+ }
+
+ template<typename L>
+ inline AutoPtr(AutoPtr<L>& other) : m_ptr(other.release())
+ {
+ }
+
+ inline T *release()
+ {
+ T *const retval = m_ptr;
+ m_ptr = 0;
+ return retval;
+ }
+
+ inline T *data() const
+ {
+ return m_ptr;
+ }
+
+ void reset(T * other = 0)
+ {
+ if(other != m_ptr)
+ {
+ delete m_ptr;
+ m_ptr = other;
+ }
+ }
+
+ inline AutoPtr &operator=(AutoPtr &other)
+ {
+ reset(other.release());
+ return *this;
+ }
+
+ private:
+ T *m_ptr;
+ };
+}
+
+QT_END_NAMESPACE
+#endif
diff --git a/src/xmlpatterns/utils/qcommonnamespaces_p.h b/src/xmlpatterns/utils/qcommonnamespaces_p.h
new file mode 100644
index 0000000..06c3eaa
--- /dev/null
+++ b/src/xmlpatterns/utils/qcommonnamespaces_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CommonNamespaces_H
+#define Patternist_CommonNamespaces_H
+
+#include <QLatin1String>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains common, standardized XML namespaces.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ namespace CommonNamespaces
+ {
+ /**
+ * Namespace for the special XML namespace. It is by definition
+ * bound to the "xml" prefix, and should have no usage in
+ * ordinary code.
+ *
+ * Specification: http://www.w3.org/TR/REC-xml-names/
+ */
+ const QLatin1String XML("http://www.w3.org/XML/1998/namespace");
+
+ /**
+ * The namespace for the xmlns prefix. The Namespaces in XML recommendation
+ * explicitly states that xmlns should not have a namespace, but has since
+ * been changed. See:
+ *
+ * http://www.w3.org/2000/xmlns/
+ */
+ const QLatin1String XMLNS("http://www.w3.org/2000/xmlns/");
+
+ /**
+ * The namespace for W3C XML Schema. This is used for the XML language it
+ * is, as well as its built-in data types.
+ *
+ * Specification: http://www.w3.org/TR/xmlschema-2/
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/datatypes.html#namespaces">XML Schema
+ * Part 2: Datatypes Second Edition, 3.1 Namespace considerations</a>
+ */
+ const QLatin1String WXS("http://www.w3.org/2001/XMLSchema");
+
+ /**
+ * The namespace for W3C XML Schema attributes used in schema instances.
+ *
+ * Specification: http://www.w3.org/TR/xmlschema-2/
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-1/structures.html#Instance_Document_Constructions">XML
+ * Schema Part 1: Structures Second Edition, 2.6 Schema-Related
+ * Markup in Documents Being Validated</a>
+ */
+ const QLatin1String XSI("http://www.w3.org/2001/XMLSchema-instance");
+
+ /**
+ * The namespace for built-in XPath functions, as defined in for example
+ * XQuery 1.0 and XPath 2.0 Functions and Operators and XSLT.
+ *
+ * Specification: http://www.w3.org/TR/xquery-operators/
+ */
+ const QLatin1String XFN("http://www.w3.org/2005/xpath-functions");
+
+ /**
+ * The namespace for XSL-T 1.0 and 2.0.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#xslt-namespace">XSL
+ * Transformations (XSLT) Version 2.0, 3.1 XSLT Namespace</a>
+ * @see <a href="http://www.w3.org/TR/xslt">XSL Transformations (XSLT) Version 1.0</a>
+ */
+ const QLatin1String XSLT("http://www.w3.org/1999/XSL/Transform");
+
+ /**
+ * The namespace for identifying errors in XPath.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-identifying-errors">XML Path Language (XPath)
+ * 2.0, 2.3.2 Identifying and Reporting Errors</a>
+ */
+ const QLatin1String XPERR("http://www.w3.org/2005/xqt-errors");
+
+ /**
+ * The XPath 2.0 Unicode codepoint collation URI identifier. Collations
+ * specifies how strings are compared and ordered.
+ */
+ const char *const UNICODE_COLLATION = "http://www.w3.org/2005/xpath-functions/collation/codepoint";
+
+ /**
+ * A namespace provided in XQuery 1.0, to easily declare local
+ * variables and functions.
+ */
+ const QLatin1String XDT_LOCAL("http://www.w3.org/2005/xquery-local-functions");
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qcppcastinghelper_p.h b/src/xmlpatterns/utils/qcppcastinghelper_p.h
new file mode 100644
index 0000000..95923a2
--- /dev/null
+++ b/src/xmlpatterns/utils/qcppcastinghelper_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_CppCastingHelper_H
+#define Patternist_CppCastingHelper_H
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides convenience methods for performing static casts between C++ classes.
+ *
+ * In Patternist, it is very common to do up-casts from Expression or Item, which typically
+ * involves writing messy code. Such an old-way cast looks like this:
+ *
+ * @code
+ * static_cast<const MyClass *>(myInstance.data())->myClassMember()
+ * @endcode
+ *
+ * CppCastingHelper provides the convenience method as() for this, which is functionally
+ * equivalent to the above code, but simpler:
+ *
+ * @code
+ * myInstance->as<MyClass>()->myClassMember()
+ * @endcode
+ *
+ * The as() function performs a static cast.
+ *
+ * By using CppCastingHelper, this is achieved:
+ *
+ * - Const correctness is automatically taken care of
+ * - Less code to write
+ * - When compiling in debug mode, the as() functions uses a @c dynamic_cast to verify that the
+ * static casts are properly done, such that sensible error messages are given when the casts
+ * are invalid. It also traps invalid casts which nevertheless happen to work on a particular
+ * platform/compiler/hardware architecture.
+ *
+ * CppCastingHelper is a template class where the TSubClass parameter must be the class
+ * inheriting CppCastingHelper. See Item or Expression for demonstration.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ template<typename TSubClass>
+ class CppCastingHelper
+ {
+ public:
+
+ /**
+ * Casts this instance to:
+ *
+ * @code
+ * const TCastTarget *
+ * @endcode
+ *
+ * and returns the result.
+ *
+ * When compiled in debug mode, this function perform a @c dynamic_cast, in order to
+ * check the correctness of the cast.
+ */
+ template<typename TCastTarget>
+ inline const TCastTarget *as() const
+ {
+#if defined(Patternist_DEBUG) && !defined(Q_CC_XLC)
+/* At least on aix-xlc-64, the compiler cries when it sees dynamic_cast. */
+ Q_ASSERT_X(dynamic_cast<const TCastTarget *>(static_cast<const TSubClass *>(this)),
+ Q_FUNC_INFO,
+ "The cast is invalid. This class does not inherit the cast target.");
+#endif
+ return static_cast<const TCastTarget *>(static_cast<const TSubClass *>(this));
+ }
+
+ /**
+ * Casts this instance to:
+ *
+ * @code
+ * TCastTarget *
+ * @endcode
+ *
+ * and returns the result.
+ *
+ * When compiled in debug mode, a @c dynamic_cast is attempted, in order to
+ * check the correctness of the cast.
+ */
+ template<typename TCastTarget>
+ inline TCastTarget *as()
+ {
+#if defined(Patternist_DEBUG) && !defined(Q_CC_XLC)
+/* At least on aix-xlc-64, the compiler cries when it sees dynamic_cast. */
+ Q_ASSERT_X(dynamic_cast<TCastTarget *>(static_cast<TSubClass *>(this)),
+ Q_FUNC_INFO,
+ "The cast is invalid. This class does not inherit the cast target.");
+#endif
+ return static_cast<TCastTarget *>(static_cast<TSubClass *>(this));
+ }
+
+ protected:
+ /**
+ * This constructor is protected because this class must be sub-classed.
+ */
+ inline CppCastingHelper() {}
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qdebug_p.h b/src/xmlpatterns/utils/qdebug_p.h
new file mode 100644
index 0000000..dcff0e0
--- /dev/null
+++ b/src/xmlpatterns/utils/qdebug_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Debug_H
+#define Patternist_Debug_H
+
+#include <QtDebug>
+/**
+ * @file
+ * @short Contains macros for debugging.
+ */
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @short Enables detailed parser debug output.
+ *
+ * If this macro is defined, @em a @em lot of debugging information will be outputted.
+ * This is all the state transitions, token shifting, and rule reductions that
+ * the parser do.
+ *
+ * This is automatically disabled if @c QT_NO_DEBUG is defined.
+ */
+#define Patternist_DEBUG_PARSER
+
+/**
+ * @short Enables debug printing statements.
+ *
+ * Patternist does not use qDebug(), but pDebug() instead. It only output
+ * if this define is defined.
+ *
+ * It is automatically disabled if @c QT_NO_DEBUG is defined.
+ */
+#define Patternist_DEBUG
+
+#undef Patternist_DEBUG // disable it for now
+
+#ifdef QT_NO_DEBUG
+# undef Patternist_DEBUG_PARSER
+# undef Patternist_DEBUG
+#endif
+
+namespace QPatternist
+{
+#ifdef Patternist_DEBUG
+ inline QDebug pDebug()
+ {
+ return qDebug();
+ }
+#else
+ inline QNoDebug pDebug()
+ {
+ return QNoDebug();
+ }
+#endif
+}
+
+QT_END_NAMESPACE
+#endif
diff --git a/src/xmlpatterns/utils/qdelegatingnamespaceresolver.cpp b/src/xmlpatterns/utils/qdelegatingnamespaceresolver.cpp
new file mode 100644
index 0000000..f44dc2a
--- /dev/null
+++ b/src/xmlpatterns/utils/qdelegatingnamespaceresolver.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnamepool_p.h"
+
+#include "qdelegatingnamespaceresolver_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DelegatingNamespaceResolver::DelegatingNamespaceResolver(const NamespaceResolver::Ptr &resolver) : m_nsResolver(resolver)
+{
+ Q_ASSERT(m_nsResolver);
+}
+
+DelegatingNamespaceResolver::DelegatingNamespaceResolver(const NamespaceResolver::Ptr &ns,
+ const Bindings &overrides) : m_nsResolver(ns)
+ , m_bindings(overrides)
+{
+ Q_ASSERT(m_nsResolver);
+}
+
+QXmlName::NamespaceCode DelegatingNamespaceResolver::lookupNamespaceURI(const QXmlName::PrefixCode prefix) const
+{
+ const QXmlName::NamespaceCode val(m_bindings.value(prefix, NoBinding));
+
+ if(val == NoBinding)
+ return m_nsResolver->lookupNamespaceURI(prefix);
+ else
+ return val;
+}
+
+NamespaceResolver::Bindings DelegatingNamespaceResolver::bindings() const
+{
+ Bindings bs(m_nsResolver->bindings());
+ const Bindings::const_iterator end(m_bindings.constEnd());
+ Bindings::const_iterator it(m_bindings.constBegin());
+
+ for(; it != end; ++it)
+ bs.insert(it.key(), it.value());
+
+ return bs;
+}
+
+void DelegatingNamespaceResolver::addBinding(const QXmlName nb)
+{
+ if(nb.namespaceURI() == StandardNamespaces::UndeclarePrefix)
+ m_bindings.remove(nb.prefix());
+ else
+ m_bindings.insert(nb.prefix(), nb.namespaceURI());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qdelegatingnamespaceresolver_p.h b/src/xmlpatterns/utils/qdelegatingnamespaceresolver_p.h
new file mode 100644
index 0000000..f446730
--- /dev/null
+++ b/src/xmlpatterns/utils/qdelegatingnamespaceresolver_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_DelegatingNamespaceResolver_H
+#define Patternist_DelegatingNamespaceResolver_H
+
+#include <QHash>
+
+#include "qnamespaceresolver_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Contains a set of bindings, plus a pointer to another resolver
+ * which is delegates requests to, in case it can't handle a lookup on its
+ * own.
+ *
+ * @ingroup Patternist
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class DelegatingNamespaceResolver : public NamespaceResolver
+ {
+ public:
+ DelegatingNamespaceResolver(const NamespaceResolver::Ptr &ns);
+ DelegatingNamespaceResolver(const NamespaceResolver::Ptr &ns,
+ const Bindings &overrides);
+
+ virtual void addBinding(const QXmlName nb);
+
+ virtual QXmlName::NamespaceCode lookupNamespaceURI(const QXmlName::PrefixCode prefix) const;
+ virtual Bindings bindings() const;
+
+ private:
+ const NamespaceResolver::Ptr m_nsResolver;
+ Bindings m_bindings;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qgenericnamespaceresolver.cpp b/src/xmlpatterns/utils/qgenericnamespaceresolver.cpp
new file mode 100644
index 0000000..4b66d6a
--- /dev/null
+++ b/src/xmlpatterns/utils/qgenericnamespaceresolver.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnamepool_p.h"
+
+#include "qgenericnamespaceresolver_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GenericNamespaceResolver::GenericNamespaceResolver(const Bindings &list) : m_bindings(list)
+{
+}
+
+void GenericNamespaceResolver::addBinding(const QXmlName nb)
+{
+ if(nb.namespaceURI() == StandardNamespaces::UndeclarePrefix)
+ m_bindings.remove(nb.prefix());
+ else
+ m_bindings.insert(nb.prefix(), nb.namespaceURI());
+}
+
+QXmlName::NamespaceCode GenericNamespaceResolver::lookupNamespaceURI(const QXmlName::PrefixCode prefix) const
+{
+ return m_bindings.value(prefix, NoBinding);
+}
+
+NamespaceResolver::Ptr GenericNamespaceResolver::defaultXQueryBindings()
+{
+ Bindings list;
+
+ list.insert(StandardPrefixes::xml, StandardNamespaces::xml);
+ list.insert(StandardPrefixes::xs, StandardNamespaces::xs);
+ list.insert(StandardPrefixes::xsi, StandardNamespaces::xsi);
+ list.insert(StandardPrefixes::fn, StandardNamespaces::fn);
+ list.insert(StandardPrefixes::local, StandardNamespaces::local);
+ list.insert(StandardPrefixes::empty, StandardNamespaces::empty);
+
+ return NamespaceResolver::Ptr(new GenericNamespaceResolver(list));
+}
+
+NamespaceResolver::Ptr GenericNamespaceResolver::defaultXSLTBindings()
+{
+ Bindings list;
+
+ list.insert(StandardPrefixes::xml, StandardNamespaces::xml);
+ list.insert(StandardPrefixes::empty, StandardNamespaces::empty);
+
+ return NamespaceResolver::Ptr(new GenericNamespaceResolver(list));
+}
+
+NamespaceResolver::Bindings GenericNamespaceResolver::bindings() const
+{
+ return m_bindings;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qgenericnamespaceresolver_p.h b/src/xmlpatterns/utils/qgenericnamespaceresolver_p.h
new file mode 100644
index 0000000..345c804
--- /dev/null
+++ b/src/xmlpatterns/utils/qgenericnamespaceresolver_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_GenericNamespaceResolver_H
+#define Patternist_GenericNamespaceResolver_H
+
+#include <QHash>
+
+#include "qnamespaceresolver_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Generic namespace resolver which resolves lookups against entries in a QHash.
+ *
+ * @ingroup Patternist
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class GenericNamespaceResolver : public NamespaceResolver
+ {
+ public:
+ GenericNamespaceResolver(const Bindings &list);
+ virtual void addBinding(const QXmlName nb);
+
+ virtual QXmlName::NamespaceCode lookupNamespaceURI(const QXmlName::PrefixCode prefix) const;
+
+ /**
+ * Returns a GenericNamespaceResolver containing the following bindings:
+ *
+ * - <tt>xml</tt> = <tt>http://www.w3.org/XML/1998/namespace</tt>
+ * - <tt>xs</tt> = <tt>http://www.w3.org/2001/XMLSchema</tt>
+ * - <tt>xsi</tt> = <tt>http://www.w3.org/2001/XMLSchema-instance</tt>
+ * - <tt>fn</tt> = <tt>http://www.w3.org/2005/xpath-functions</tt>
+ * - <tt>xdt</tt> = <tt>http://www.w3.org/2005/xpath-datatypes</tt>
+ * - no prefix = empty namespace
+ */
+ static NamespaceResolver::Ptr defaultXQueryBindings();
+
+ /**
+ * Returns a GenericNamespaceResolver containing the following bindings:
+ *
+ * - <tt>xml</tt> = <tt>http://www.w3.org/XML/1998/namespace</tt>
+ * - no prefix = empty namespace
+ */
+ static NamespaceResolver::Ptr defaultXSLTBindings();
+
+ virtual Bindings bindings() const;
+
+ private:
+ /**
+ * The key is the prefix, the value the namespace URI.
+ */
+ Bindings m_bindings;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qnamepool.cpp b/src/xmlpatterns/utils/qnamepool.cpp
new file mode 100644
index 0000000..9ada593
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamepool.cpp
@@ -0,0 +1,418 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDebug>
+
+#include "private/qxmlutils_p.h"
+#include "qxpathhelper_p.h"
+
+#include "qnamepool_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamePool::NamePool()
+{
+ m_localNameMapping .reserve(DefaultLocalNameCapacity + StandardLocalNameCount);
+ m_localNames .reserve(DefaultLocalNameCapacity + StandardLocalNameCount);
+ m_namespaceMapping .reserve(DefaultURICapacity + StandardNamespaceCount);
+ m_namespaces .reserve(DefaultURICapacity + StandardNamespaceCount);
+ m_prefixes .reserve(DefaultPrefixCapacity + StandardPrefixCount);
+ m_prefixMapping .reserve(DefaultPrefixCapacity + StandardPrefixCount);
+
+ /* Namespaces. */
+ {
+ unlockedAllocateNamespace(QString());
+ unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2005/xpath-functions"));
+ unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2005/xquery-local-functions"));
+ unlockedAllocateNamespace(QLatin1String("http://www.w3.org/XML/1998/namespace"));
+ unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2000/xmlns/"));
+ unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2001/XMLSchema"));
+ unlockedAllocateNamespace(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"));
+ unlockedAllocateNamespace(QLatin1String("http://www.w3.org/1999/XSL/Transform"));
+
+ /* For UndeclarePrefix, StopNamespaceInheritance and InternalXSLT. We use two
+ * arbitrary strings that aren't used. For instance, if we just used an
+ * empty QString, unlockedAllocateNamespace() would assign it
+ * StandardNamespaces::empty. However, it's important that the string
+ * is an invalid namespace, since otherwise user strings would get
+ * assigned the same IDs. */
+ unlockedAllocateNamespace(QLatin1String(" | 1 "));
+ unlockedAllocateNamespace(QLatin1String(" | 2 "));
+ unlockedAllocateNamespace(QLatin1String(" | InternalXSLT"));
+
+ Q_ASSERT_X(m_namespaces.count() == StandardNamespaceCount, Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("Expected is %1, actual is %2.").arg(StandardNamespaceCount).arg(m_namespaces.count())));
+ }
+
+ /* Prefixes. */
+ {
+ unlockedAllocatePrefix(QString());
+ unlockedAllocatePrefix(QLatin1String("fn"));
+ unlockedAllocatePrefix(QLatin1String("local"));
+ unlockedAllocatePrefix(QLatin1String("xml"));
+ unlockedAllocatePrefix(QLatin1String("xmlns"));
+ unlockedAllocatePrefix(QLatin1String("xs"));
+ unlockedAllocatePrefix(QLatin1String("xsi"));
+ unlockedAllocatePrefix(QLatin1String("ns0"));
+ unlockedAllocatePrefix(QLatin1String("|||")); /* Invalid NCName, for StopNamespaceInheritance. */
+
+ Q_ASSERT_X(m_prefixes.count() == StandardPrefixCount, Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("Expected is %1, actual is %2.").arg(StandardPrefixCount).arg(m_prefixes.count())));
+ }
+
+ /* Local names. */
+ {
+ /* Same order as the enum in StandardLocalNames. That is, alphabetically. */
+ unlockedAllocateLocalName(QLatin1String("abs"));
+ unlockedAllocateLocalName(QLatin1String("adjust-dateTime-to-timezone"));
+ unlockedAllocateLocalName(QLatin1String("adjust-date-to-timezone"));
+ unlockedAllocateLocalName(QLatin1String("adjust-time-to-timezone"));
+ unlockedAllocateLocalName(QLatin1String("all"));
+ unlockedAllocateLocalName(QLatin1String("arity"));
+ unlockedAllocateLocalName(QLatin1String("avg"));
+ unlockedAllocateLocalName(QLatin1String("base"));
+ unlockedAllocateLocalName(QLatin1String("base-uri"));
+ unlockedAllocateLocalName(QLatin1String("boolean"));
+ unlockedAllocateLocalName(QLatin1String("ceiling"));
+ unlockedAllocateLocalName(QLatin1String("codepoint-equal"));
+ unlockedAllocateLocalName(QLatin1String("codepoints-to-string"));
+ unlockedAllocateLocalName(QLatin1String("collection"));
+ unlockedAllocateLocalName(QLatin1String("compare"));
+ unlockedAllocateLocalName(QLatin1String("concat"));
+ unlockedAllocateLocalName(QLatin1String("contains"));
+ unlockedAllocateLocalName(QLatin1String("count"));
+ unlockedAllocateLocalName(QLatin1String("current"));
+ unlockedAllocateLocalName(QLatin1String("current-date"));
+ unlockedAllocateLocalName(QLatin1String("current-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("current-time"));
+ unlockedAllocateLocalName(QLatin1String("data"));
+ unlockedAllocateLocalName(QLatin1String("dateTime"));
+ unlockedAllocateLocalName(QLatin1String("day-from-date"));
+ unlockedAllocateLocalName(QLatin1String("day-from-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("days-from-duration"));
+ unlockedAllocateLocalName(QLatin1String("deep-equal"));
+ unlockedAllocateLocalName(QLatin1String("default"));
+ unlockedAllocateLocalName(QLatin1String("default-collation"));
+ unlockedAllocateLocalName(QLatin1String("distinct-values"));
+ unlockedAllocateLocalName(QLatin1String("doc"));
+ unlockedAllocateLocalName(QLatin1String("doc-available"));
+ unlockedAllocateLocalName(QLatin1String("document"));
+ unlockedAllocateLocalName(QLatin1String("document-uri"));
+ unlockedAllocateLocalName(QLatin1String("element-available"));
+ unlockedAllocateLocalName(QLatin1String("empty"));
+ unlockedAllocateLocalName(QLatin1String("encode-for-uri"));
+ unlockedAllocateLocalName(QLatin1String("ends-with"));
+ unlockedAllocateLocalName(QLatin1String("error"));
+ unlockedAllocateLocalName(QLatin1String("escape-html-uri"));
+ unlockedAllocateLocalName(QLatin1String("exactly-one"));
+ unlockedAllocateLocalName(QLatin1String("exists"));
+ unlockedAllocateLocalName(QLatin1String("false"));
+ unlockedAllocateLocalName(QLatin1String("floor"));
+ unlockedAllocateLocalName(QLatin1String("function-available"));
+ unlockedAllocateLocalName(QLatin1String("function-name"));
+ unlockedAllocateLocalName(QLatin1String("generate-id"));
+ unlockedAllocateLocalName(QLatin1String("generic-string-join"));
+ unlockedAllocateLocalName(QLatin1String("hours-from-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("hours-from-duration"));
+ unlockedAllocateLocalName(QLatin1String("hours-from-time"));
+ unlockedAllocateLocalName(QLatin1String("id"));
+ unlockedAllocateLocalName(QLatin1String("idref"));
+ unlockedAllocateLocalName(QLatin1String("implicit-timezone"));
+ unlockedAllocateLocalName(QLatin1String("index-of"));
+ unlockedAllocateLocalName(QLatin1String("in-scope-prefixes"));
+ unlockedAllocateLocalName(QLatin1String("insert-before"));
+ unlockedAllocateLocalName(QLatin1String("iri-to-uri"));
+ unlockedAllocateLocalName(QLatin1String("is-schema-aware"));
+ unlockedAllocateLocalName(QLatin1String("key"));
+ unlockedAllocateLocalName(QLatin1String("lang"));
+ unlockedAllocateLocalName(QLatin1String("last"));
+ unlockedAllocateLocalName(QLatin1String("local-name"));
+ unlockedAllocateLocalName(QLatin1String("local-name-from-QName"));
+ unlockedAllocateLocalName(QLatin1String("lower-case"));
+ unlockedAllocateLocalName(QLatin1String("matches"));
+ unlockedAllocateLocalName(QLatin1String("max"));
+ unlockedAllocateLocalName(QLatin1String("min"));
+ unlockedAllocateLocalName(QLatin1String("minutes-from-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("minutes-from-duration"));
+ unlockedAllocateLocalName(QLatin1String("minutes-from-time"));
+ unlockedAllocateLocalName(QLatin1String("month-from-date"));
+ unlockedAllocateLocalName(QLatin1String("month-from-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("months-from-duration"));
+ unlockedAllocateLocalName(QLatin1String("name"));
+ unlockedAllocateLocalName(QLatin1String("namespace-uri"));
+ unlockedAllocateLocalName(QLatin1String("namespace-uri-for-prefix"));
+ unlockedAllocateLocalName(QLatin1String("namespace-uri-from-QName"));
+ unlockedAllocateLocalName(QLatin1String("nilled"));
+ unlockedAllocateLocalName(QLatin1String("node-name"));
+ unlockedAllocateLocalName(QLatin1String("normalize-space"));
+ unlockedAllocateLocalName(QLatin1String("normalize-unicode"));
+ unlockedAllocateLocalName(QLatin1String("not"));
+ unlockedAllocateLocalName(QLatin1String("number"));
+ unlockedAllocateLocalName(QLatin1String("one-or-more"));
+ unlockedAllocateLocalName(QLatin1String("position"));
+ unlockedAllocateLocalName(QLatin1String("prefix-from-QName"));
+ unlockedAllocateLocalName(QLatin1String("product-name"));
+ unlockedAllocateLocalName(QLatin1String("product-version"));
+ unlockedAllocateLocalName(QLatin1String("property-name"));
+ unlockedAllocateLocalName(QLatin1String("QName"));
+ unlockedAllocateLocalName(QLatin1String("remove"));
+ unlockedAllocateLocalName(QLatin1String("replace"));
+ unlockedAllocateLocalName(QLatin1String("resolve-QName"));
+ unlockedAllocateLocalName(QLatin1String("resolve-uri"));
+ unlockedAllocateLocalName(QLatin1String("reverse"));
+ unlockedAllocateLocalName(QLatin1String("root"));
+ unlockedAllocateLocalName(QLatin1String("round"));
+ unlockedAllocateLocalName(QLatin1String("round-half-to-even"));
+ unlockedAllocateLocalName(QLatin1String("seconds-from-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("seconds-from-duration"));
+ unlockedAllocateLocalName(QLatin1String("seconds-from-time"));
+ unlockedAllocateLocalName(QLatin1String("sourceValue"));
+ unlockedAllocateLocalName(QLatin1String("starts-with"));
+ unlockedAllocateLocalName(QLatin1String("static-base-uri"));
+ unlockedAllocateLocalName(QLatin1String("string"));
+ unlockedAllocateLocalName(QLatin1String("string-join"));
+ unlockedAllocateLocalName(QLatin1String("string-length"));
+ unlockedAllocateLocalName(QLatin1String("string-to-codepoints"));
+ unlockedAllocateLocalName(QLatin1String("subsequence"));
+ unlockedAllocateLocalName(QLatin1String("substring"));
+ unlockedAllocateLocalName(QLatin1String("substring-after"));
+ unlockedAllocateLocalName(QLatin1String("substring-before"));
+ unlockedAllocateLocalName(QLatin1String("sum"));
+ unlockedAllocateLocalName(QLatin1String("supports-backwards-compatibility"));
+ unlockedAllocateLocalName(QLatin1String("supports-serialization"));
+ unlockedAllocateLocalName(QLatin1String("system-property"));
+ unlockedAllocateLocalName(QLatin1String("timezone-from-date"));
+ unlockedAllocateLocalName(QLatin1String("timezone-from-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("timezone-from-time"));
+ unlockedAllocateLocalName(QLatin1String("tokenize"));
+ unlockedAllocateLocalName(QLatin1String("trace"));
+ unlockedAllocateLocalName(QLatin1String("translate"));
+ unlockedAllocateLocalName(QLatin1String("true"));
+ unlockedAllocateLocalName(QLatin1String("type-available"));
+ unlockedAllocateLocalName(QLatin1String("unordered"));
+ unlockedAllocateLocalName(QLatin1String("unparsed-entity-public-id"));
+ unlockedAllocateLocalName(QLatin1String("unparsed-entity-uri"));
+ unlockedAllocateLocalName(QLatin1String("unparsed-text"));
+ unlockedAllocateLocalName(QLatin1String("unparsed-text-available"));
+ unlockedAllocateLocalName(QLatin1String("upper-case"));
+ unlockedAllocateLocalName(QLatin1String("vendor"));
+ unlockedAllocateLocalName(QLatin1String("vendor-url"));
+ unlockedAllocateLocalName(QLatin1String("version"));
+ unlockedAllocateLocalName(QLatin1String("xml"));
+ unlockedAllocateLocalName(QLatin1String("xmlns"));
+ unlockedAllocateLocalName(QLatin1String("year-from-date"));
+ unlockedAllocateLocalName(QLatin1String("year-from-dateTime"));
+ unlockedAllocateLocalName(QLatin1String("years-from-duration"));
+ unlockedAllocateLocalName(QLatin1String("zero-or-one"));
+ Q_ASSERT(m_localNames.count() == StandardLocalNameCount);
+ }
+}
+
+QXmlName NamePool::allocateQName(const QString &uri, const QString &localName, const QString &prefix)
+{
+ QWriteLocker l(&lock);
+
+ /*
+ QString codepoints;
+ for(int i = 0; i < localName.length(); ++i)
+ codepoints.append(QString::number(localName.at(i).unicode()) + QLatin1Char(' '));
+
+ pDebug() << Q_FUNC_INFO << localName << "codepoints:" << codepoints;
+ */
+
+ Q_ASSERT_X(QXmlUtils::isNCName(localName), Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("'%1' is an invalid NCName.").arg(localName)));
+
+ const QXmlName::NamespaceCode nsCode = unlockedAllocateNamespace(uri);
+ const QXmlName::LocalNameCode localCode = unlockedAllocateLocalName(localName);
+
+ Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix));
+ const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix);
+
+ return QXmlName(nsCode, localCode, prefixCode);
+}
+
+QXmlName NamePool::allocateBinding(const QString &prefix, const QString &uri)
+{
+ QWriteLocker l(&lock);
+
+ Q_ASSERT_X(prefix.isEmpty() || QXmlUtils::isNCName(prefix), Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("%1 is an invalid prefix.").arg(prefix)));
+ const QXmlName::NamespaceCode nsCode = unlockedAllocateNamespace(uri);
+
+ Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix));
+ const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix);
+
+ return QXmlName(nsCode, StandardLocalNames::empty, prefixCode);
+}
+
+QXmlName::LocalNameCode NamePool::unlockedAllocateLocalName(const QString &ln)
+{
+ Q_ASSERT_X(QXmlUtils::isNCName(ln), Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("Invalid local name: \"%1\"").arg(ln)));
+
+ int indexInLocalNames = m_localNameMapping.value(ln, NoSuchValue);
+
+ if(indexInLocalNames == NoSuchValue)
+ {
+ indexInLocalNames = m_localNames.count();
+ m_localNames.append(ln);
+ m_localNameMapping.insert(ln, indexInLocalNames);
+ }
+
+ return indexInLocalNames;
+}
+
+QXmlName::PrefixCode NamePool::unlockedAllocatePrefix(const QString &prefix)
+{
+ int indexInPrefixes = m_prefixMapping.value(prefix, NoSuchValue);
+
+ if(indexInPrefixes == NoSuchValue)
+ {
+ indexInPrefixes = m_prefixes.count();
+ m_prefixes.append(prefix);
+ m_prefixMapping.insert(prefix, indexInPrefixes);
+ }
+
+ return indexInPrefixes;
+}
+
+QXmlName::NamespaceCode NamePool::unlockedAllocateNamespace(const QString &uri)
+{
+ int indexInURIs = m_namespaceMapping.value(uri, NoSuchValue);
+
+ if(indexInURIs == NoSuchValue)
+ {
+ indexInURIs = m_namespaces.count();
+ m_namespaces.append(uri);
+ m_namespaceMapping.insert(uri, indexInURIs);
+ }
+
+ return indexInURIs;
+}
+
+const QString &NamePool::displayPrefix(const QXmlName::NamespaceCode nc) const
+{
+ switch(nc)
+ {
+ case StandardNamespaces::xmlns: return m_prefixes.at(StandardPrefixes::xmlns);
+ case StandardNamespaces::local: return m_prefixes.at(StandardPrefixes::local);
+ case StandardNamespaces::xs: return m_prefixes.at(StandardPrefixes::xs);
+ case StandardNamespaces::xml: return m_prefixes.at(StandardPrefixes::xml);
+ case StandardNamespaces::fn: return m_prefixes.at(StandardPrefixes::fn);
+ default: return m_prefixes.at(StandardPrefixes::empty);
+ }
+}
+
+QString NamePool::displayName(const QXmlName qName) const
+{
+ QReadLocker l(&lock);
+
+ if(qName.hasNamespace())
+ {
+ if(qName.namespaceURI() == StandardNamespaces::InternalXSLT)
+ return QLatin1Char('#') + m_localNames.at(qName.localName());
+
+ const QString &p = displayPrefix(qName.namespaceURI());
+
+ if(p.isEmpty())
+ return QLatin1Char('{') + m_namespaces.at(qName.namespaceURI()) + QLatin1Char('}') + toLexical(qName);
+ else
+ return p + QLatin1Char(':') + m_localNames.at(qName.localName());
+ }
+ else
+ return m_localNames.at(qName.localName());
+}
+
+QString NamePool::toClarkName(const QXmlName &name) const
+{
+ if(name.isNull())
+ return QLatin1String("QXmlName(null)");
+ else
+ {
+ if(name.hasNamespace())
+ {
+ const QString ns(stringForNamespace(name.namespaceURI()));
+ const QString p(stringForPrefix(name.prefix()));
+ const QString l(stringForLocalName(name.localName()));
+
+ return QChar::fromLatin1('{')
+ + ns
+ + QChar::fromLatin1('}')
+ + (p.isEmpty() ? l : p + QChar::fromLatin1(':') + l);
+ }
+ else
+ return stringForLocalName(name.localName());
+ }
+}
+
+QXmlName NamePool::fromClarkName(const QString &clarkName)
+{
+ if(clarkName.isEmpty())
+ return QXmlName();
+
+ if(clarkName.at(0) == QLatin1Char('{'))
+ {
+ const int indexOfRight = clarkName.indexOf(QLatin1Char('}'));
+ const QString qName(clarkName.right((clarkName.length() - indexOfRight) - 1));
+
+ if(!XPathHelper::isQName(qName))
+ return QXmlName();
+
+ QString localName;
+ QString prefix;
+
+ XPathHelper::splitQName(qName, prefix, localName);
+
+ return allocateQName(clarkName.mid(1, indexOfRight - 1),
+ localName, prefix);
+ }
+ else
+ {
+ if(QXmlName::isNCName(clarkName))
+ return allocateQName(QString(), clarkName);
+ else
+ return QXmlName();
+ }
+}
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qnamepool_p.h b/src/xmlpatterns/utils/qnamepool_p.h
new file mode 100644
index 0000000..8d1beb9
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamepool_p.h
@@ -0,0 +1,556 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamePool_H
+#define Patternist_NamePool_H
+
+#include <QHash>
+#include <QReadLocker>
+#include <QReadWriteLock>
+#include <QSharedData>
+#include <QString>
+#include <QVector>
+#include <QXmlName>
+
+#include <QtXmlPatterns/private/qprimitives_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Store names such as namespace bindings and QNames and allows them to
+ * be referenced in efficient ways.
+ *
+ * Once a string have been inserted it stays there and cannot be removed. The
+ * only way to deallocate any string in the NamePool is to deallocate the
+ * NamePool itself, as a whole.
+ *
+ * This class is not only reentrant, it is thread-safe in all sense of the
+ * word. All functions of this class can be called concurrently. This is
+ * achieved by internal locking.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo Use QSubStrings, we can save very many heap allocations by that.
+ * @todo Check limits
+ */
+ class Q_AUTOTEST_EXPORT NamePool : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NamePool> Ptr;
+
+ private:
+ friend class StandardNamespaces;
+
+ enum
+ {
+ NoSuchValue = -1,
+ /**
+ * This must be identical to the amount of members in
+ * StandardNamespaces.
+ */
+ StandardNamespaceCount = 11,
+ StandardPrefixCount = 9,
+ StandardLocalNameCount = 141
+ };
+
+ QVector<QString> m_prefixes;
+ QVector<QString> m_namespaces;
+ QVector<QString> m_localNames;
+
+ /**
+ * This hash contains no essential data, but speeds up
+ * finding a prefix in m_prefixes by mapping a prefix(the key) to
+ * the index into m_prefixes(which the value is).
+ *
+ * In other words, one can skip this variable at the cost of having
+ * to linearly loop over prefixes, in order to find the entry.
+ */
+ QHash<QString, QXmlName::PrefixCode> m_prefixMapping;
+
+ /**
+ * Same as m_prefixMapping but applies for URIs, and hence m_namespaces instead
+ * of m_prefixes.
+ */
+ QHash<QString, QXmlName::NamespaceCode> m_namespaceMapping;
+
+ QHash<QString, QXmlName::LocalNameCode> m_localNameMapping;
+
+ enum DefaultCapacities
+ {
+ DefaultPrefixCapacity = 10,
+ DefaultURICapacity = DefaultPrefixCapacity,
+ /**
+ * It looks like it's quite common with 40-60 different local names per XML
+ * vocabulary. For background, see:
+ *
+ * - http://englich.wordpress.com/2007/01/11/representing-xml/
+ * - http://englich.wordpress.com/2007/01/09/xmlstat/
+ */
+ DefaultLocalNameCapacity = 60
+ };
+
+ public:
+ NamePool();
+
+ /**
+ * @short Allocates a namespace binding for @p prefix and @p uri.
+ *
+ * In the returned QXmlName, the local name is
+ * StandardLocalNames::empty, and QXmlName::prefix() and
+ * QXmlName::namespaceUri() returns @p prefix and @p uri, respectively.
+ *
+ * In older versions of this code, the class NamespaceBinding existed,
+ * but as part of having the public class QXmlName, it was dropped and
+ * a special interpretation/convention involving use of QXmlName was
+ * adopted.
+ */
+ QXmlName allocateBinding(const QString &prefix, const QString &uri);
+
+ QXmlName allocateQName(const QString &uri, const QString &localName, const QString &prefix = QString());
+
+ inline QXmlName allocateQName(const QXmlName::NamespaceCode uri, const QString &ln)
+ {
+ /* We don't lock here, but we do in allocateLocalName(). */
+ return QXmlName(uri, allocateLocalName(ln));
+ }
+
+ inline const QString &stringForLocalName(const QXmlName::LocalNameCode code) const
+ {
+ const QReadLocker l(&lock);
+ return m_localNames.at(code);
+ }
+
+ inline const QString &stringForPrefix(const QXmlName::PrefixCode code) const
+ {
+ const QReadLocker l(&lock);
+ return m_prefixes.at(code);
+ }
+
+ inline const QString &stringForNamespace(const QXmlName::NamespaceCode code) const
+ {
+ const QReadLocker l(&lock);
+ return m_namespaces.at(code);
+ }
+
+ QString displayName(const QXmlName qName) const;
+
+ inline QString toLexical(const QXmlName qName) const
+ {
+ const QReadLocker l(&lock);
+ Q_ASSERT_X(!qName.isNull(), "", "It makes no sense to call toLexical() on a null name.");
+
+ if(qName.hasPrefix())
+ {
+ const QString &p = m_prefixes.at(qName.prefix());
+ return p + QLatin1Char(':') + m_localNames.at(qName.localName());
+ }
+ else
+ return m_localNames.at(qName.localName());
+ }
+
+ inline QXmlName::NamespaceCode allocateNamespace(const QString &uri)
+ {
+ const QWriteLocker l(&lock);
+ return unlockedAllocateNamespace(uri);
+ }
+
+ inline QXmlName::LocalNameCode allocateLocalName(const QString &ln)
+ {
+ const QWriteLocker l(&lock);
+ return unlockedAllocateLocalName(ln);
+ }
+
+ inline QXmlName::PrefixCode allocatePrefix(const QString &prefix)
+ {
+ const QWriteLocker l(&lock);
+ return unlockedAllocatePrefix(prefix);
+ }
+
+ QString toClarkName(const QXmlName &name) const;
+ QXmlName fromClarkName(const QString &clarkName);
+
+ private:
+ /**
+ * @note This function can not be called concurrently.
+ */
+ QXmlName::NamespaceCode unlockedAllocateNamespace(const QString &uri);
+
+ /**
+ * @note This function can not be called concurrently.
+ */
+ QXmlName::LocalNameCode unlockedAllocateLocalName(const QString &ln);
+
+ /**
+ * It's assumed that @p prefix is a valid @c NCName.
+ *
+ * @note This function can not be called concurrently.
+ */
+ QXmlName::PrefixCode unlockedAllocatePrefix(const QString &prefix);
+
+ Q_DISABLE_COPY(NamePool)
+
+ /**
+ * @note This function can not be called concurrently.
+ */
+ const QString &displayPrefix(const QXmlName::NamespaceCode nc) const;
+
+ mutable QReadWriteLock lock;
+ };
+
+ /**
+ * @short Formats QName.
+ *
+ * @relates QXmlName
+ */
+ static inline QString formatKeyword(const NamePool::Ptr &np, const QXmlName name)
+ {
+ return QLatin1String("<span class='XQuery-keyword'>") +
+ escape(np->displayName(name)) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * @see NamespaceResolver::Constants
+ */
+ class StandardNamespaces
+ {
+ public:
+ enum ID
+ {
+ /**
+ * This does not mean empty in the sense of "empty", but
+ * in the sense of an empty string, "".
+ *
+ * Its value, zero, is significant.
+ */
+ empty = 0,
+ fn,
+ local,
+ xml,
+ xmlns,
+ xs,
+ xsi,
+ xslt,
+ /**
+ * @short A special value that when passed as the namespace part
+ * to NamespaceResolver::addBinding(), undeclares the prefix.
+ *
+ * This is used by the namespace prolog declaration.
+ *
+ * A dummy value is added to the name pool.
+ */
+ UndeclarePrefix,
+
+ /**
+ * Signals that a node shouldn't inherit namespaces from its parent. Must be used
+ * with StandardPrefixes::StopNamespaceInheritance.
+ */
+ StopNamespaceInheritance,
+
+ /**
+ * A namespace used to identify for instance @c \#all template
+ * mode in XSL-T.
+ */
+ InternalXSLT
+ };
+ };
+
+ // const QString * a = &*qset.insert("foo");
+ class StandardLocalNames
+ {
+ public:
+ enum
+ {
+ abs,
+ adjust_dateTime_to_timezone,
+ adjust_date_to_timezone,
+ adjust_time_to_timezone,
+ all,
+ arity,
+ avg,
+ base,
+ base_uri,
+ boolean,
+ ceiling,
+ codepoint_equal,
+ codepoints_to_string,
+ collection,
+ compare,
+ concat,
+ contains,
+ count,
+ current,
+ current_date,
+ current_dateTime,
+ current_time,
+ data,
+ dateTime,
+ day_from_date,
+ day_from_dateTime,
+ days_from_duration,
+ deep_equal,
+ Default,
+ default_collation,
+ distinct_values,
+ doc,
+ doc_available,
+ document,
+ document_uri,
+ element_available,
+ empty,
+ encode_for_uri,
+ ends_with,
+ error,
+ escape_html_uri,
+ exactly_one,
+ exists,
+ False,
+ floor,
+ function_available,
+ function_name,
+ generate_id,
+ generic_string_join,
+ hours_from_dateTime,
+ hours_from_duration,
+ hours_from_time,
+ id,
+ idref,
+ implicit_timezone,
+ index_of,
+ in_scope_prefixes,
+ insert_before,
+ iri_to_uri,
+ is_schema_aware,
+ key,
+ lang,
+ last,
+ local_name,
+ local_name_from_QName,
+ lower_case,
+ matches,
+ max,
+ min,
+ minutes_from_dateTime,
+ minutes_from_duration,
+ minutes_from_time,
+ month_from_date,
+ month_from_dateTime,
+ months_from_duration,
+ name,
+ namespace_uri,
+ namespace_uri_for_prefix,
+ namespace_uri_from_QName,
+ nilled,
+ node_name,
+ normalize_space,
+ normalize_unicode,
+ Not,
+ number,
+ one_or_more,
+ position,
+ prefix_from_QName,
+ product_name,
+ product_version,
+ property_name,
+ QName,
+ remove,
+ replace,
+ resolve_QName,
+ resolve_uri,
+ reverse,
+ root,
+ round,
+ round_half_to_even,
+ seconds_from_dateTime,
+ seconds_from_duration,
+ seconds_from_time,
+ sourceValue,
+ starts_with,
+ static_base_uri,
+ string,
+ string_join,
+ string_length,
+ string_to_codepoints,
+ subsequence,
+ substring,
+ substring_after,
+ substring_before,
+ sum,
+ supports_backwards_compatibility,
+ supports_serialization,
+ system_property,
+ timezone_from_date,
+ timezone_from_dateTime,
+ timezone_from_time,
+ tokenize,
+ trace,
+ translate,
+ True,
+ type_available,
+ unordered,
+ unparsed_entity_public_id,
+ unparsed_entity_uri,
+ unparsed_text,
+ unparsed_text_available,
+ upper_case,
+ vendor,
+ vendor_url,
+ version,
+ xml,
+ xmlns,
+ year_from_date,
+ year_from_dateTime,
+ years_from_duration,
+ zero_or_one
+ };
+ };
+
+ class StandardPrefixes
+ {
+ public:
+ enum
+ {
+ /**
+ * This does not mean empty in the sense of "empty", but
+ * in the sense of an empty string, "".
+ *
+ * Its value, zero, is significant.
+ */
+ empty = 0,
+ fn,
+ local,
+ xml,
+ xmlns,
+ xs,
+ xsi,
+ ns0,
+ StopNamespaceInheritance
+ };
+ };
+}
+
+inline QXmlName::LocalNameCode QXmlName::localName() const
+{
+ return (m_qNameCode & LocalNameMask) >> LocalNameOffset;
+}
+
+inline QXmlName::PrefixCode QXmlName::prefix() const
+{
+ return (m_qNameCode & PrefixMask) >> PrefixOffset;
+}
+
+inline bool QXmlName::hasPrefix() const
+{
+ return prefix() != 0;
+}
+
+inline bool QXmlName::hasNamespace() const
+{
+ return namespaceURI() != 0;
+}
+
+inline QXmlName::NamespaceCode QXmlName::namespaceURI() const
+{
+ return (m_qNameCode & NamespaceMask) >> NamespaceOffset;
+}
+
+inline bool QXmlName::isLexicallyEqual(const QXmlName &other) const
+{
+ return (m_qNameCode & LexicalQNameMask) == (other.m_qNameCode & LexicalQNameMask);
+}
+
+inline void QXmlName::setPrefix(const PrefixCode c)
+{
+ m_qNameCode |= (c << PrefixOffset);
+}
+
+inline void QXmlName::setNamespaceURI(const NamespaceCode c)
+{
+ m_qNameCode |= (c << NamespaceOffset);
+}
+
+inline void QXmlName::setLocalName(const LocalNameCode c)
+{
+ m_qNameCode |= (c << LocalNameOffset);
+}
+
+inline QXmlName::Code QXmlName::code() const
+{
+ return m_qNameCode;
+}
+
+inline QXmlName::QXmlName(const NamespaceCode uri,
+ const LocalNameCode ln,
+ const PrefixCode p) : m_qNameCode((uri << NamespaceOffset) +
+ (ln << LocalNameOffset) +
+ (p << PrefixOffset))
+{
+ /* We can't use members like prefix() here because if one of the
+ * values are to large, they would overflow into the others. */
+ Q_ASSERT_X(p <= MaximumPrefixes, "",
+ qPrintable(QString::fromLatin1("NamePool prefix limits: max is %1, therefore %2 exceeds.").arg(MaximumPrefixes).arg(p)));
+ Q_ASSERT_X(ln <= MaximumLocalNames, "",
+ qPrintable(QString::fromLatin1("NamePool local name limits: max is %1, therefore %2 exceeds.").arg(MaximumLocalNames).arg(ln)));
+ Q_ASSERT_X(uri <= MaximumNamespaces, "",
+ qPrintable(QString::fromLatin1("NamePool namespace limits: max is %1, therefore %2 exceeds.").arg(MaximumNamespaces).arg(uri)));
+}
+
+
+Q_DECLARE_TYPEINFO(QPatternist::NamePool::Ptr, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qnamespacebinding_p.h b/src/xmlpatterns/utils/qnamespacebinding_p.h
new file mode 100644
index 0000000..01e38a2
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamespacebinding_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamespaceBinding_H
+#define Patternist_NamespaceBinding_H
+
+template<typename T> class QVector;
+
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a namespace binding: a prefix, and a namespace URI.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NamespaceBinding
+ {
+ public:
+ enum
+ {
+ InvalidCode = -1
+ };
+
+ typedef QVector<NamespaceBinding> Vector;
+
+ inline NamespaceBinding() : m_prefix(InvalidCode),
+ m_namespace(InvalidCode)
+ {
+ }
+
+ inline NamespaceBinding(const QXmlName::PrefixCode p,
+ const QXmlName::NamespaceCode n) : m_prefix(p),
+ m_namespace(n)
+ {
+ }
+
+ inline bool operator==(const NamespaceBinding &other) const
+ {
+ return m_prefix == other.m_prefix &&
+ m_namespace == other.m_namespace;
+ }
+
+ inline QXmlName::PrefixCode prefix() const
+ {
+ return m_prefix;
+ }
+
+ inline QXmlName::NamespaceCode namespaceURI() const
+ {
+ return m_namespace;
+ }
+
+ inline bool isNull() const
+ {
+ return m_prefix == InvalidCode;
+ }
+
+ /**
+ * @short Constructs a NamespaceBinding whose prefix and namespace is
+ * taken from @p qName.
+ *
+ * The local name in @p qName is ignored. @p qName may not be null.
+ */
+ static inline NamespaceBinding fromQXmlName(const QXmlName qName)
+ {
+ Q_ASSERT(!qName.isNull());
+ return NamespaceBinding(qName.prefix(), qName.namespaceURI());
+ }
+
+ private:
+ QXmlName::PrefixCode m_prefix;
+ QXmlName::NamespaceCode m_namespace;
+ };
+
+ /**
+ * @relates NamespaceBinding
+ */
+ static inline uint qHash(const NamespaceBinding nb)
+ {
+ return (nb.prefix() << 16) + nb.namespaceURI();
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qnamespaceresolver.cpp b/src/xmlpatterns/utils/qnamespaceresolver.cpp
new file mode 100644
index 0000000..d3e08c3
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamespaceresolver.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnamespaceresolver_p.h"
+#include "qnamepool_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamespaceResolver::NamespaceResolver()
+{
+}
+
+NamespaceResolver::~NamespaceResolver()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qnamespaceresolver_p.h b/src/xmlpatterns/utils/qnamespaceresolver_p.h
new file mode 100644
index 0000000..24e3eff
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamespaceresolver_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NamespaceResolver_H
+#define Patternist_NamespaceResolver_H
+
+#include <QSharedData>
+#include <QXmlName>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename A, typename B> class QHash;
+
+namespace QPatternist
+{
+
+ /**
+ * @short Base class for namespace resolvers.
+ *
+ * @ingroup Patternist
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NamespaceResolver : public QSharedData
+ {
+ public:
+ enum Constants
+ {
+ NoBinding = -1
+ };
+
+ typedef QExplicitlySharedDataPointer<NamespaceResolver> Ptr;
+
+ /**
+ * A list of namespace bindings. The key is the prefix, and the value is
+ * the namespace URI.
+ */
+ typedef QHash<QXmlName::PrefixCode, QXmlName::NamespaceCode> Bindings;
+
+ NamespaceResolver();
+ virtual ~NamespaceResolver();
+
+ /**
+ * Adds the mapping from @p prefix to @p namespaceURI to
+ * this NamespaceResolver. If this NamespaceResolver already contains
+ * a binding involving @p prefix, the old binding is replaced.
+ */
+ virtual void addBinding(const QXmlName nb) = 0;
+
+ /**
+ * Resolves the @p prefix to the corresponding namespace URI. If no binding
+ * exists for @p prefix, NoBinding is returned.
+ *
+ * @returns the namespace corresponding to @p prefix.
+ */
+ virtual QXmlName::NamespaceCode lookupNamespaceURI(const QXmlName::PrefixCode prefix) const = 0;
+
+ /**
+ * @returns all bindings this NamespaceResolver handles.
+ */
+ virtual Bindings bindings() const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qnodenamespaceresolver.cpp b/src/xmlpatterns/utils/qnodenamespaceresolver.cpp
new file mode 100644
index 0000000..f921057
--- /dev/null
+++ b/src/xmlpatterns/utils/qnodenamespaceresolver.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+#include "qnamepool_p.h"
+
+#include "qnodenamespaceresolver_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NodeNamespaceResolver::NodeNamespaceResolver(const Item &item) : m_node(item.asNode())
+{
+ Q_ASSERT(!m_node.isNull());
+}
+
+void NodeNamespaceResolver::addBinding(const QXmlName nb)
+{
+ Q_UNUSED(nb);
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Calling this function for this sub-class makes little sense.");
+}
+
+QXmlName::NamespaceCode NodeNamespaceResolver::lookupNamespaceURI(const QXmlName::PrefixCode prefix) const
+{
+ const QXmlName::NamespaceCode ns = m_node.namespaceForPrefix(prefix);
+
+ if(ns == NoBinding)
+ {
+ if(prefix == StandardPrefixes::empty)
+ return StandardNamespaces::empty;
+ else
+ return NoBinding;
+ }
+ else
+ return ns;
+}
+
+NamespaceResolver::Bindings NodeNamespaceResolver::bindings() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented.");
+ return NamespaceResolver::Bindings();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qnodenamespaceresolver_p.h b/src/xmlpatterns/utils/qnodenamespaceresolver_p.h
new file mode 100644
index 0000000..2ed2de1
--- /dev/null
+++ b/src/xmlpatterns/utils/qnodenamespaceresolver_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_NodeNamespaceResolver_H
+#define Patternist_NodeNamespaceResolver_H
+
+#include <QHash>
+
+#include "qnamespaceresolver_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A NamespaceResolver that use a QXmlNodeModelIndex's in-scope namespace
+ * bindings for resolving namespaces.
+ *
+ * @ingroup Patternist
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class NodeNamespaceResolver : public NamespaceResolver
+ {
+ public:
+ NodeNamespaceResolver(const Item &item);
+
+ virtual void addBinding(const QXmlName nb);
+ virtual QXmlName::NamespaceCode lookupNamespaceURI(const QXmlName::PrefixCode prefix) const;
+ virtual Bindings bindings() const;
+
+ private:
+ const QXmlNodeModelIndex m_node;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qoutputvalidator.cpp b/src/xmlpatterns/utils/qoutputvalidator.cpp
new file mode 100644
index 0000000..a3f0816
--- /dev/null
+++ b/src/xmlpatterns/utils/qoutputvalidator.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpatternistlocale_p.h"
+
+#include "qoutputvalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+OutputValidator::OutputValidator(QAbstractXmlReceiver *const receiver,
+ const DynamicContext::Ptr &context,
+ const SourceLocationReflection *const r,
+ const bool isXSLT) : DelegatingSourceLocationReflection(r)
+ , m_hasReceivedChildren(false)
+ , m_receiver(receiver)
+ , m_context(context)
+ , m_isXSLT(isXSLT)
+{
+ Q_ASSERT(receiver);
+ Q_ASSERT(context);
+}
+
+void OutputValidator::namespaceBinding(const QXmlName &nb)
+{
+ m_receiver->namespaceBinding(nb);
+}
+
+void OutputValidator::startElement(const QXmlName &name)
+{
+ m_hasReceivedChildren = false;
+ m_receiver->startElement(name);
+ m_attributes.clear();
+}
+
+void OutputValidator::endElement()
+{
+ m_hasReceivedChildren = true;
+ m_receiver->endElement();
+}
+
+void OutputValidator::attribute(const QXmlName &name,
+ const QStringRef &value)
+{
+ if(m_hasReceivedChildren)
+ {
+ m_context->error(QtXmlPatterns::tr("It's not possible to add attributes after any other kind of node."),
+ m_isXSLT ? ReportContext::XTDE0410 : ReportContext::XQTY0024, this);
+ }
+ else
+ {
+ if(!m_isXSLT && m_attributes.contains(name))
+ {
+ m_context->error(QtXmlPatterns::tr("An attribute by name %1 has already been created.").arg(formatKeyword(m_context->namePool(), name)),
+ ReportContext::XQDY0025, this);
+ }
+ else
+ {
+ m_attributes.insert(name);
+ m_receiver->attribute(name, value);
+ }
+ }
+}
+
+void OutputValidator::comment(const QString &value)
+{
+ m_hasReceivedChildren = true;
+ m_receiver->comment(value);
+}
+
+void OutputValidator::characters(const QStringRef &value)
+{
+ m_hasReceivedChildren = true;
+ m_receiver->characters(value);
+}
+
+void OutputValidator::processingInstruction(const QXmlName &name,
+ const QString &value)
+{
+ m_hasReceivedChildren = true;
+ m_receiver->processingInstruction(name, value);
+}
+
+void OutputValidator::item(const Item &outputItem)
+{
+ /* We can't send outputItem directly to m_receiver since its item() function
+ * won't dispatch to this OutputValidator, but to itself. We're not sub-classing here,
+ * we're delegating. */
+
+ if(outputItem.isNode())
+ sendAsNode(outputItem);
+ else
+ {
+ m_hasReceivedChildren = true;
+ m_receiver->item(outputItem);
+ }
+}
+
+void OutputValidator::startDocument()
+{
+ m_receiver->startDocument();
+}
+
+void OutputValidator::endDocument()
+{
+ m_receiver->endDocument();
+}
+
+void OutputValidator::atomicValue(const QVariant &value)
+{
+ Q_UNUSED(value);
+ // TODO
+}
+
+void OutputValidator::endOfSequence()
+{
+}
+
+void OutputValidator::startOfSequence()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qoutputvalidator_p.h b/src/xmlpatterns/utils/qoutputvalidator_p.h
new file mode 100644
index 0000000..b5a7923
--- /dev/null
+++ b/src/xmlpatterns/utils/qoutputvalidator_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_OutputValidator_H
+#define Patternist_OutputValidator_H
+
+#include <QSet>
+
+#include "qdynamiccontext_p.h"
+#include "qabstractxmlreceiver.h"
+#include "qsourcelocationreflection_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Receives QAbstractXmlReceiver events and validates that they are correct,
+ * before sending them on to a second QAbstractXmlReceiver.
+ *
+ * Currently, this is only checking that attributes appear before other
+ * nodes.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo Escape data
+ */
+ class OutputValidator : public QAbstractXmlReceiver
+ , public DelegatingSourceLocationReflection
+ {
+ public:
+ OutputValidator(QAbstractXmlReceiver *const receiver,
+ const DynamicContext::Ptr &context,
+ const SourceLocationReflection *const r,
+ const bool isXSLT);
+
+ virtual void namespaceBinding(const QXmlName &nb);
+
+ virtual void characters(const QStringRef &value);
+ virtual void comment(const QString &value);
+
+ virtual void startElement(const QXmlName &name);
+
+ virtual void endElement();
+
+ virtual void attribute(const QXmlName &name,
+ const QStringRef &value);
+
+ virtual void processingInstruction(const QXmlName &name,
+ const QString &value);
+
+ virtual void item(const Item &item);
+
+ virtual void startDocument();
+ virtual void endDocument();
+ virtual void atomicValue(const QVariant &value);
+ virtual void endOfSequence();
+ virtual void startOfSequence();
+
+ private:
+ bool m_hasReceivedChildren;
+ QAbstractXmlReceiver *const m_receiver;
+ const DynamicContext::Ptr m_context;
+
+ /**
+ * Keeps the current received attributes, in order to check uniqueness.
+ */
+ QSet<QXmlName> m_attributes;
+ const bool m_isXSLT;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/qpatternistlocale.cpp b/src/xmlpatterns/utils/qpatternistlocale.cpp
new file mode 100644
index 0000000..1a9ad85
--- /dev/null
+++ b/src/xmlpatterns/utils/qpatternistlocale.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpatternistlocale_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ QString escape(const QString &input)
+ {
+ QString rich;
+ rich.reserve(int(input.length() * 1.1));
+
+ for(int i = 0; i < input.length(); ++i)
+ {
+ switch(input.at(i).unicode())
+ {
+ case '<':
+ {
+ rich += QLatin1String("&lt;");
+ break;
+ }
+ case '>':
+ {
+ rich += QLatin1String("&gt;");
+ break;
+ }
+ case '&':
+ {
+ rich += QLatin1String("&amp;");
+ break;
+ }
+ case '"':
+ {
+ rich += QLatin1String("&quot;");
+ break;
+ }
+ case '\'':
+ {
+ rich += QLatin1String("&apos;");
+ break;
+ }
+ default:
+ rich += input.at(i);
+ }
+ }
+
+ return rich;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qpatternistlocale_p.h b/src/xmlpatterns/utils/qpatternistlocale_p.h
new file mode 100644
index 0000000..2ecdb1d
--- /dev/null
+++ b/src/xmlpatterns/utils/qpatternistlocale_p.h
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_Locale_H
+#define Patternist_Locale_H
+
+#include <QCoreApplication>
+#include <QString>
+#include <QUrl>
+
+#include "qcardinality_p.h"
+#include "qnamepool_p.h"
+#include "qprimitives_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @file
+ * @short Contains functions used for formatting arguments, such as keywords and paths,
+ * in translated strings.
+ */
+
+namespace QPatternist
+{
+ /**
+ * @short Provides a translation context & functions for the QtXmlPatterns
+ * module.
+ *
+ * This class is not supposed to be instantiated.
+ */
+ class QtXmlPatterns
+ {
+ public:
+ Q_DECLARE_TR_FUNCTIONS(QtXmlPatterns)
+
+ private:
+ /**
+ * No implementation is provided, this class is not supposed to be
+ * instantiated.
+ */
+ inline QtXmlPatterns();
+ Q_DISABLE_COPY(QtXmlPatterns)
+ };
+
+ // don't make this function static, otherwise xlC 7 cannot find it
+ inline QString formatKeyword(const QString &keyword)
+ {
+ return QLatin1String("<span class='XQuery-keyword'>") +
+ escape(keyword) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * @overload
+ */
+ static inline QString formatKeyword(const QStringRef &keyword)
+ {
+ return formatKeyword(keyword.toString());
+ }
+
+ static inline QString formatKeyword(const char *const keyword)
+ {
+ return formatKeyword(QLatin1String(keyword));
+ }
+
+ static inline QString formatKeyword(const QChar keyword)
+ {
+ return formatKeyword(QString(keyword));
+ }
+
+ /**
+ * @short Formats element name.
+ */
+ static inline QString formatElement(const QString &element)
+ {
+ // for the moment we forward to formatKeyword, that will change later
+ return formatKeyword(element);
+ }
+
+ /**
+ * @overload
+ */
+ static inline QString formatElement(const char *const element)
+ {
+ return formatElement(QLatin1String(element));
+ }
+
+ /**
+ * @short Formats attribute name.
+ */
+ static inline QString formatAttribute(const QString &attribute)
+ {
+ // for the moment we forward to formatKeyword, that will change later
+ return formatKeyword(attribute);
+ }
+
+ /**
+ * @overload
+ */
+ static inline QString formatAttribute(const char *const attribute)
+ {
+ return formatAttribute(QLatin1String(attribute));
+ }
+
+ /**
+ * @short Formats ItemType and SequenceType.
+ *
+ * This function is not declared static, because the compiler on target
+ * aix-xlc-64 won't accept it.
+ */
+ template<typename T>
+ inline QString formatType(const NamePool::Ptr &np, const T &type)
+ {
+ Q_ASSERT(type);
+ return QLatin1String("<span class='XQuery-type'>") +
+ escape(type->displayName(np)) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * @short Formats name of any type.
+ */
+ static inline QString formatType(const NamePool::Ptr &np, const QXmlName &name)
+ {
+ return QLatin1String("<span class='XQuery-type'>") +
+ escape(np->displayName(name)) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * @short Formats Cardinality.
+ */
+ static inline QString formatType(const Cardinality &type)
+ {
+ return QLatin1String("<span class='XQuery-type'>") +
+ escape(type.displayName(Cardinality::IncludeExplanation)) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * @short Formats @p uri as a path to a resource, typically it's a filename
+ * or a URI.
+ */
+ static inline QString formatResourcePath(const QUrl &uri)
+ {
+ const QString normalizedURI(escape(uri.toString(QUrl::RemovePassword)));
+
+ return QLatin1String("<span class='XQuery-filepath'><a href='") +
+ normalizedURI +
+ QLatin1String("'>") +
+ normalizedURI +
+ QLatin1String("</a></span>");
+ }
+
+ /**
+ * @short Formats @p uri for display.
+ *
+ * @note It's not guaranteed that URIs being formatted are valid. That can
+ * be an arbitrary string.
+ */
+ static inline QString formatURI(const QUrl &uri)
+ {
+ return QLatin1String("<span class='XQuery-uri'>") +
+ escape(uri.toString(QUrl::RemovePassword)) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * @short Formats @p uri, that's considered to be a URI, for display.
+ *
+ * @p uri does not have to be a valid QUrl or valid instance of @c
+ * xs:anyURI.
+ */
+ static inline QString formatURI(const QString &uri)
+ {
+ const QUrl realURI(uri);
+ return formatURI(realURI);
+ }
+
+ static inline QString formatData(const QString &data)
+ {
+ return QLatin1String("<span class='XQuery-data'>") +
+ escape(data) +
+ QLatin1String("</span>");
+ }
+
+ /**
+ * This is an overload, provided for convenience.
+ */
+ static inline QString formatData(const xsInteger data)
+ {
+ return formatData(QString::number(data));
+ }
+
+ /**
+ * This is an overload, provided for convenience.
+ */
+ static inline QString formatData(const char *const data)
+ {
+ return formatData(QLatin1String(data));
+ }
+
+ /**
+ * This is an overload, provided for convenience.
+ */
+ static inline QString formatData(const QLatin1Char &data)
+ {
+ return formatData(QString(data));
+ }
+
+ /**
+ * Formats an arbitrary expression, such as a regular expression
+ * or XQuery query.
+ */
+ static inline QString formatExpression(const QString &expr)
+ {
+ return QLatin1String("<span class='XQuery-expression'>") +
+ escape(expr) +
+ QLatin1String("</span>");
+ }
+
+}
+
+#ifdef Q_NO_TYPESAFE_FLAGS
+#error "Patternist does not compile with Q_NO_TYPESAFE_FLAGS set, because the code uses negative enum values. qglobal.h has typedef uint Flags."
+#endif
+
+#ifdef QT_NO_EXCEPTIONS
+#error "Patternist uses exceptions and cannot be built without."
+#endif
+
+QT_END_NAMESPACE
+#endif
diff --git a/src/xmlpatterns/utils/qxpathhelper.cpp b/src/xmlpatterns/utils/qxpathhelper.cpp
new file mode 100644
index 0000000..7bca2eb
--- /dev/null
+++ b/src/xmlpatterns/utils/qxpathhelper.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "private/qxmlutils_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qnamepool_p.h"
+
+#include "qxpathhelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XPathHelper::isReservedNamespace(const QXmlName::NamespaceCode ns)
+{
+ /* The order is because of that XFN and WXS are the most common. */
+ return ns == StandardNamespaces::fn ||
+ ns == StandardNamespaces::xs ||
+ ns == StandardNamespaces::xml ||
+ ns == StandardNamespaces::xsi;
+}
+
+bool XPathHelper::isQName(const QString &qName)
+{
+ const QStringList result(qName.split(QLatin1Char(':')));
+ const int c = result.count();
+
+ if(c == 2)
+ {
+ return QXmlUtils::isNCName(result.first()) &&
+ QXmlUtils::isNCName(result.last());
+ }
+ else if(c == 1)
+ return QXmlUtils::isNCName(result.first());
+ else
+ return false;
+}
+
+void XPathHelper::splitQName(const QString &qName, QString &prefix, QString &ncName)
+{
+ Q_ASSERT_X(isQName(qName), Q_FUNC_INFO,
+ "qName must be a valid QName.");
+
+ const QStringList result(qName.split(QLatin1Char(':')));
+
+ if(result.count() == 1)
+ {
+ Q_ASSERT(QXmlUtils::isNCName(result.first()));
+ ncName = result.first();
+ }
+ else
+ {
+ Q_ASSERT(result.count() == 2);
+ Q_ASSERT(QXmlUtils::isNCName(result.first()));
+ Q_ASSERT(QXmlUtils::isNCName(result.last()));
+
+ prefix = result.first();
+ ncName = result.last();
+ }
+}
+
+ItemType::Ptr XPathHelper::typeFromKind(const QXmlNodeModelIndex::NodeKind nodeKind)
+{
+ switch(nodeKind)
+ {
+ case QXmlNodeModelIndex::Element:
+ return BuiltinTypes::element;
+ case QXmlNodeModelIndex::Attribute:
+ return BuiltinTypes::attribute;
+ case QXmlNodeModelIndex::Text:
+ return BuiltinTypes::text;
+ case QXmlNodeModelIndex::ProcessingInstruction:
+ return BuiltinTypes::pi;
+ case QXmlNodeModelIndex::Comment:
+ return BuiltinTypes::comment;
+ case QXmlNodeModelIndex::Document:
+ return BuiltinTypes::document;
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "A node type that doesn't exist in the XPath Data Model was encountered.");
+ return ItemType::Ptr(); /* Dummy, silence compiler warning. */
+ }
+ }
+}
+
+QUrl XPathHelper::normalizeQueryURI(const QUrl &uri)
+{
+ Q_ASSERT_X(uri.isEmpty() || uri.isValid(), Q_FUNC_INFO,
+ "The URI passed to QXmlQuery::setQuery() must be valid or empty.");
+ if(uri.isEmpty())
+ return QUrl::fromLocalFile(QCoreApplication::applicationFilePath());
+ else if(uri.isRelative())
+ return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(uri);
+ else
+ return uri;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qxpathhelper_p.h b/src/xmlpatterns/utils/qxpathhelper_p.h
new file mode 100644
index 0000000..b947d2f
--- /dev/null
+++ b/src/xmlpatterns/utils/qxpathhelper_p.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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_XPathHelper_H
+#define Patternist_XPathHelper_H
+
+#include "qcommonnamespaces_p.h"
+#include "qitem_p.h"
+#include "qpatternistlocale_p.h"
+#include "qreportcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains helper and utility functions.
+ *
+ * The common denominator of its functions is that they do not fit in
+ * well elsewhere, such as in a particular class. It is preferred if XPathHelper
+ * goes away, and that functions are in more specific classes.
+ *
+ * @ingroup Patternist
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class XPathHelper
+ {
+ public:
+ /**
+ * Determines whether @p qName is a valid QName. For example, "body" and "xhtml:body"
+ * is, but "xhtml::body" or "x:body "(note the whitespace) is not.
+ *
+ * @see QNameConstructor::expandQName()
+ * @see QNameValue
+ */
+ static bool isQName(const QString &qName);
+
+ /**
+ * @short Splits @p qName into @p localName and @p prefix.
+ *
+ * @note @p qName must be a valid QName, and that is not checked.
+ */
+ static void splitQName(const QString &qName, QString &prefix, QString &localName);
+
+ /**
+ * Determines whether @p ns is a reserved namespace.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#reserved-namespaces">XSL Transformations
+ * (XSLT) Version 2.0, 3.2 Reserved Namespaces</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#FunctionDeclns">XQuery 1.0: An XML
+ * Query Language, 4.15 Function Declaration</a>
+ * @returns @c true if @p ns is a reserved namespace, otherwise @c false.
+ */
+ static bool isReservedNamespace(const QXmlName::NamespaceCode ns);
+
+ /**
+ * Determines whether @p collation is a supported string collation. If it is
+ * not, error code @p code is raised via @p context.
+ */
+ template<const ReportContext::ErrorCode code, typename TReportContext>
+ static inline void checkCollationSupport(const QString &collation,
+ const TReportContext &context,
+ const SourceLocationReflection *const r)
+ {
+ Q_ASSERT(context);
+ Q_ASSERT(r);
+
+ if(collation != QLatin1String(CommonNamespaces::UNICODE_COLLATION))
+ {
+ context->error(QtXmlPatterns::tr("Only the Unicode Codepoint "
+ "Collation is supported(%1). %2 is unsupported.")
+ .arg(formatURI(QLatin1String(CommonNamespaces::UNICODE_COLLATION)))
+ .arg(formatURI(collation)),
+ code, r);
+ }
+ }
+
+ static QPatternist::ItemTypePtr typeFromKind(const QXmlNodeModelIndex::NodeKind nodeKind);
+
+ /**
+ * Normalizes an @p uri by resolving it to the application directory if empty.
+ */
+ static QUrl normalizeQueryURI(const QUrl &uri);
+
+ /**
+ * @short Determines whether @p consists only of whitespace. Characters
+ * considered whitespace are the ones for which QChar::isSpace() returns @c true for.
+ *
+ * For the empty string, @c true is returned.
+ *
+ * @returns @c true if @p string consists only of whitespace, otherwise @c false.
+ */
+ static inline bool isWhitespaceOnly(const QStringRef &string)
+ {
+ const int len = string.length();
+
+ for(int i = 0; i < len; ++i)
+ {
+ if(!string.at(i).isSpace()) // TODO and this is wrong, see sdk/TODO
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @overload
+ */
+ static inline bool isWhitespaceOnly(const QString &string)
+ {
+ return isWhitespaceOnly(QStringRef(&string));
+ }
+
+ private:
+ /**
+ * @short This default constructor has no definition, in order to avoid
+ * instantiation, since it makes no sense to instantiate this class.
+ */
+ inline XPathHelper();
+
+ Q_DISABLE_COPY(XPathHelper)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/utils/utils.pri b/src/xmlpatterns/utils/utils.pri
new file mode 100644
index 0000000..2db91c2
--- /dev/null
+++ b/src/xmlpatterns/utils/utils.pri
@@ -0,0 +1,21 @@
+HEADERS += $$PWD/qautoptr_p.h \
+ $$PWD/qcommonnamespaces_p.h \
+ $$PWD/qcppcastinghelper_p.h \
+ $$PWD/qdebug_p.h \
+ $$PWD/qgenericnamespaceresolver_p.h \
+ $$PWD/qpatternistlocale_p.h \
+ $$PWD/qnamepool_p.h \
+ $$PWD/qnamespaceresolver_p.h \
+ $$PWD/qoutputvalidator_p.h \
+ $$PWD/qxpathhelper_p.h \
+ $$PWD/qdelegatingnamespaceresolver_p.h \
+ $$PWD/qnodenamespaceresolver_p.h
+
+SOURCES += $$PWD/qgenericnamespaceresolver.cpp \
+ $$PWD/qpatternistlocale.cpp \
+ $$PWD/qnamepool.cpp \
+ $$PWD/qnamespaceresolver.cpp \
+ $$PWD/qoutputvalidator.cpp \
+ $$PWD/qxpathhelper.cpp \
+ $$PWD/qdelegatingnamespaceresolver.cpp \
+ $$PWD/qnodenamespaceresolver.cpp
diff --git a/src/xmlpatterns/xmlpatterns.pro b/src/xmlpatterns/xmlpatterns.pro
new file mode 100644
index 0000000..d22f417
--- /dev/null
+++ b/src/xmlpatterns/xmlpatterns.pro
@@ -0,0 +1,37 @@
+TARGET = QtXmlPatterns
+QPRO_PWD = $$PWD
+QT = core \
+ network
+DEFINES += QT_BUILD_XMLPATTERNS_LIB \
+ QT_NO_USING_NAMESPACE
+win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x61000000
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore \
+ QtNetwork
+include(../qbase.pri)
+PRECOMPILED_HEADER = ../corelib/global/qt_pch.h
+include($$PWD/common.pri)
+include($$PWD/acceltree/acceltree.pri)
+include($$PWD/api/api.pri)
+include($$PWD/data/data.pri)
+include($$PWD/environment/environment.pri)
+include($$PWD/expr/expr.pri)
+include($$PWD/functions/functions.pri)
+include($$PWD/iterators/iterators.pri)
+include($$PWD/janitors/janitors.pri)
+include($$PWD/parser/parser.pri)
+include($$PWD/projection/projection.pri)
+include($$PWD/schema/schema.pri)
+include($$PWD/type/type.pri)
+include($$PWD/utils/utils.pri)
+include($$PWD/qobjectmodel/qobjectmodel.pri, "", true)
+
+wince* {
+ # The Microsoft MIPS compiler crashes if /Og is specified.
+ # -O2/1 expands to /Og plus additional arguments.
+ contains(DEFINES, MIPS) {
+ QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/
+ QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/
+ }
+}
+
+symbian:TARGET.UID3 = 0x2001E62B