summaryrefslogtreecommitdiffstats
path: root/src/xmlpatterns
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 10:18:55 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 10:18:55 +0100
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/xmlpatterns
Long live Qt 4.5!
Diffstat (limited to 'src/xmlpatterns')
-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.cpp706
-rw-r--r--src/xmlpatterns/acceltree/qacceltree_p.h404
-rw-r--r--src/xmlpatterns/acceltree/qacceltreebuilder.cpp429
-rw-r--r--src/xmlpatterns/acceltree/qacceltreebuilder_p.h187
-rw-r--r--src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp411
-rw-r--r--src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h195
-rw-r--r--src/xmlpatterns/acceltree/qcompressedwhitespace.cpp197
-rw-r--r--src/xmlpatterns/acceltree/qcompressedwhitespace_p.h186
-rw-r--r--src/xmlpatterns/api/api.pri48
-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.h328
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel.cpp1669
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel.h423
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel_p.h71
-rw-r--r--src/xmlpatterns/api/qabstractxmlreceiver.cpp476
-rw-r--r--src/xmlpatterns/api/qabstractxmlreceiver.h106
-rw-r--r--src/xmlpatterns/api/qabstractxmlreceiver_p.h71
-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/qreferencecountedvalue_p.h106
-rw-r--r--src/xmlpatterns/api/qresourcedelegator.cpp111
-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.cpp109
-rw-r--r--src/xmlpatterns/api/qxmlnamepool.h88
-rw-r--r--src/xmlpatterns/api/qxmlquery.cpp1179
-rw-r--r--src/xmlpatterns/api/qxmlquery.h147
-rw-r--r--src/xmlpatterns/api/qxmlquery_p.h330
-rw-r--r--src/xmlpatterns/api/qxmlresultitems.cpp149
-rw-r--r--src/xmlpatterns/api/qxmlresultitems.h76
-rw-r--r--src/xmlpatterns/api/qxmlresultitems_p.h87
-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.pri17
-rw-r--r--src/xmlpatterns/data/data.pri78
-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.cpp71
-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.cpp228
-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/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.h542
-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.cpp92
-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/qyearmonthduration.cpp186
-rw-r--r--src/xmlpatterns/data/qyearmonthduration_p.h151
-rw-r--r--src/xmlpatterns/documentationGroups.dox150
-rwxr-xr-xsrc/xmlpatterns/environment/createReportContext.sh12
-rw-r--r--src/xmlpatterns/environment/createReportContext.xsl554
-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.cpp340
-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.cpp478
-rw-r--r--src/xmlpatterns/environment/qreportcontext_p.h2460
-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.cpp211
-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.cpp219
-rw-r--r--src/xmlpatterns/expr/qcastingplatform_p.h197
-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.cpp480
-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.cpp211
-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.cpp300
-rw-r--r--src/xmlpatterns/functions/qpatternplatform_p.h183
-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.cpp353
-rw-r--r--src/xmlpatterns/functions/qsequencefns_p.h338
-rw-r--r--src/xmlpatterns/functions/qsequencegeneratingfns.cpp304
-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.sh15
-rwxr-xr-xsrc/xmlpatterns/parser/createTokenLookup.sh5
-rwxr-xr-xsrc/xmlpatterns/parser/createXSLTTokenLookup.sh3
-rw-r--r--src/xmlpatterns/parser/parser.pri19
-rw-r--r--src/xmlpatterns/parser/qmaintainingreader.cpp273
-rw-r--r--src/xmlpatterns/parser/qmaintainingreader_p.h233
-rw-r--r--src/xmlpatterns/parser/qparsercontext.cpp100
-rw-r--r--src/xmlpatterns/parser/qparsercontext_p.h433
-rw-r--r--src/xmlpatterns/parser/qquerytransformparser.cpp7976
-rw-r--r--src/xmlpatterns/parser/qquerytransformparser_p.h307
-rw-r--r--src/xmlpatterns/parser/qtokenizer_p.h216
-rw-r--r--src/xmlpatterns/parser/qtokenlookup.cpp404
-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.ypp4572
-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.sed20
-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/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.cpp83
-rw-r--r--src/xmlpatterns/type/qanysimpletype_p.h118
-rw-r--r--src/xmlpatterns/type/qanytype.cpp93
-rw-r--r--src/xmlpatterns/type/qanytype_p.h132
-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/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.h202
-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.cpp75
-rw-r--r--src/xmlpatterns/type/qschematype_p.h222
-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.pri70
-rw-r--r--src/xmlpatterns/utils/qautoptr.cpp50
-rw-r--r--src/xmlpatterns/utils/qautoptr_p.h177
-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.h273
-rw-r--r--src/xmlpatterns/utils/qxpathhelper.cpp128
-rw-r--r--src/xmlpatterns/utils/qxpathhelper_p.h174
-rw-r--r--src/xmlpatterns/utils/utils.pri21
-rw-r--r--src/xmlpatterns/xmlpatterns.pro35
631 files changed, 120993 insertions, 0 deletions
diff --git a/src/xmlpatterns/.gitignore b/src/xmlpatterns/.gitignore
new file mode 100644
index 0000000000..eb12d93781
--- /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 0000000000..60a6c77ced
--- /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 =
+
+# 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 0000000000..6d77e9c519
--- /dev/null
+++ b/src/xmlpatterns/Mainpage.dox
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+/**
+ * @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 <fenglich@trolltech.com>
+ */
diff --git a/src/xmlpatterns/acceltree/acceltree.pri b/src/xmlpatterns/acceltree/acceltree.pri
new file mode 100644
index 0000000000..284371a1c9
--- /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 0000000000..152c5d863e
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceliterators.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..545ff7330a
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceliterators_p.h
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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<fenglich@trolltech.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<fenglich@trolltech.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<fenglich@trolltech.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<fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..60e6e272d9
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltree.cpp
@@ -0,0 +1,706 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStack>
+
+#include "qabstractxmlreceiver.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;
+
+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);
+ }
+
+}
+
+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 0000000000..10320bae4f
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltree_p.h
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 AccelTree : public QAbstractXmlNodeModel
+ {
+ public:
+ using QAbstractXmlNodeModel::createIndex;
+
+ typedef QExplicitlySharedDataPointer<AccelTree> Ptr;
+ typedef qint32 PreNumber;
+ typedef PreNumber PostNumber;
+ typedef qint8 Depth;
+
+ inline AccelTree(const QUrl &docURI,
+ const QUrl &bURI) : 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);
+ }
+
+ /**
+ * @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 <fenglich@trolltech.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:
+ 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 8 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;
+
+ 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:
+ /**
+ * 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 0000000000..5b16cc32dc
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreebuilder.cpp
@@ -0,0 +1,429 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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) : 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)
+{
+ 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)
+{
+ startStructure();
+
+ m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Element, -1, name));
+
+ ++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 0000000000..653eb8559f
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreebuilder_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.com>
+ */
+ template<bool FromDocument>
+ class AccelTreeBuilder : public NodeBuilder
+ , public SourceLocationReflection
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<AccelTreeBuilder> Ptr;
+
+ /**
+ * @param context may be @c null.
+ */
+ AccelTreeBuilder(const QUrl &docURI,
+ const QUrl &baseURI,
+ const NamePool::Ptr &np,
+ ReportContext *const context);
+ virtual void startDocument();
+ virtual void endDocument();
+ virtual void startElement(const QXmlName &name);
+ 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;
+ };
+
+#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 0000000000..4a5c2192a2
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp
@@ -0,0 +1,411 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTimer>
+#include <QtCore/QXmlStreamReader>
+
+#include <QtNetwork/QNetworkRequest>
+
+#include "qacceltreebuilder_p.h"
+#include "qatomicstring_p.h"
+#include "qautoptr_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "qacceltreeresourceloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+static inline uint qHash(const QUrl &uri)
+{
+ return qHash(uri.toString());
+}
+
+AccelTreeResourceLoader::AccelTreeResourceLoader(const NamePool::Ptr &np,
+ const NetworkAccessDelegator::Ptr &manager) : m_namePool(np)
+ , m_networkAccessDelegator(manager)
+{
+ 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());
+
+ 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;
+}
+
+QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri,
+ const NetworkAccessDelegator::Ptr &networkDelegator,
+ const ReportContext::Ptr &context)
+{
+ return load(uri,
+ networkDelegator->managerFor(uri),
+ context);
+}
+
+QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri,
+ QNetworkAccessManager *const networkManager,
+ const ReportContext::Ptr &context)
+{
+ 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())
+ {
+ 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)
+ context->error(errorMessage, ReportContext::FODC0002, location);
+
+ return 0;
+ }
+ else
+ return reply;
+}
+
+bool AccelTreeResourceLoader::streamToReceiver(QIODevice *const dev,
+ QAbstractXmlReceiver *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()));
+
+ /* 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();
+ }
+}
+
+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 0000000000..863fd65610
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AccelTreeResourceLoader_H
+#define Patternist_AccelTreeResourceLoader_H
+
+#include <QtCore/QHash>
+#include <QtCore/QEventLoop>
+#include <QtNetwork/QNetworkReply>
+
+#include "qabstractxmlreceiver.h"
+#include "qacceltree_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 <fenglich@trolltech.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 <fenglich@trolltech.com>
+ */
+ class Q_AUTOTEST_EXPORT AccelTreeResourceLoader : public DeviceResourceLoader
+ {
+ public:
+ /**
+ * AccelTreeResourceLoader does not own @p context.
+ */
+ AccelTreeResourceLoader(const NamePool::Ptr &np,
+ const NetworkAccessDelegator::Ptr &networkDelegator);
+
+ 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 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);
+
+ /**
+ * @overload
+ */
+ static QNetworkReply *load(const QUrl &uri,
+ const NetworkAccessDelegator::Ptr &networkDelegator,
+ const ReportContext::Ptr &context);
+
+ /**
+ * @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,
+ QAbstractXmlReceiver *const receiver,
+ const NamePool::Ptr &np,
+ const ReportContext::Ptr &context,
+ const QUrl &uri);
+ bool retrieveDocument(const QUrl &uri,
+ 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;
+ };
+}
+
+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 0000000000..730d1d93aa
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qcompressedwhitespace.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..92bc0a55eb
--- /dev/null
+++ b/src/xmlpatterns/acceltree/qcompressedwhitespace_p.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.com>
+ */
+ class 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 0000000000..a0298f25fb
--- /dev/null
+++ b/src/xmlpatterns/api/api.pri
@@ -0,0 +1,48 @@
+HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \
+ $$PWD/qabstractmessagehandler.h \
+ $$PWD/qabstracturiresolver.h \
+ $$PWD/qabstractxmlnodemodel.h \
+ $$PWD/qabstractxmlnodemodel_p.h \
+ $$PWD/qabstractxmlreceiver.h \
+ $$PWD/qabstractxmlreceiver_p.h \
+ $$PWD/qdeviceresourceloader_p.h \
+ $$PWD/qiodevicedelegate_p.h \
+ $$PWD/qnetworkaccessdelegator_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/qxmlserializer.h \
+ $$PWD/qxmlserializer_p.h \
+ $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler_p.h \
+ $$PWD/../../../tools/xmlpatterns/qcoloroutput_p.h
+
+SOURCES += $$PWD/qvariableloader.cpp \
+ $$PWD/qabstractmessagehandler.cpp \
+ $$PWD/qabstracturiresolver.cpp \
+ $$PWD/qabstractxmlnodemodel.cpp \
+ $$PWD/qabstractxmlreceiver.cpp \
+ $$PWD/qiodevicedelegate.cpp \
+ $$PWD/qnetworkaccessdelegator.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/qxmlserializer.cpp \
+ $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler.cpp \
+ $$PWD/../../../tools/xmlpatterns/qcoloroutput.cpp
+
+INCLUDEPATH += $$PWD/../../../tools/xmlpatterns/
diff --git a/src/xmlpatterns/api/qabstractmessagehandler.cpp b/src/xmlpatterns/api/qabstractmessagehandler.cpp
new file mode 100644
index 0000000000..1792bb5ac8
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractmessagehandler.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..efc22376db
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractmessagehandler.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..b1f708be21
--- /dev/null
+++ b/src/xmlpatterns/api/qabstracturiresolver.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "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 0000000000..ec850279b4
--- /dev/null
+++ b/src/xmlpatterns/api/qabstracturiresolver.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..5bddeeebb4
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlforwarditerator.cpp
@@ -0,0 +1,269 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \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 <fenglich@trolltech.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 0000000000..836218e5fc
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QABSTRACTXMLFORWARDITERATOR_H
+#define QABSTRACTXMLFORWARDITERATOR_H
+
+#include <QtCore/QList>
+#include <QtCore/QVector>
+#include <QtCore/QSharedData>
+
+
+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;
+}
+
+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() {}
+ 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 0000000000..0caa8c48f4
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
@@ -0,0 +1,1669 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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{Thread Support in Qt#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()
+{
+ delete d_ptr;
+}
+
+/*!
+ \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 ide 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.");
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.h b/src/xmlpatterns/api/qabstractxmlnodemodel.h
new file mode 100644
index 0000000000..6c9574c420
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel.h
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTXMLNODEMODEL_H
+#define QABSTRACTXMLNODEMODEL_H
+
+#include <QtXmlPatterns/QXmlName>
+#include <QtCore/QSharedData>
+
+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 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;
+ 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;
+
+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);
+ }
+
+ QAbstractXmlNodeModelPrivate *d_ptr;
+private:
+ friend class QPatternist::ItemMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >;
+ friend class QPatternist::SequenceMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *>;
+
+ 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 0000000000..16ce6134a5
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists 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
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractXmlNodeModelPrivate
+{
+public:
+ virtual ~QAbstractXmlNodeModelPrivate()
+ {
+ }
+};
+
+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 0000000000..ddd01e4a96
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlreceiver.cpp
@@ -0,0 +1,476 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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()
+{
+ delete d_ptr;
+}
+
+/*!
+ \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 0000000000..355576a198
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlreceiver.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTXMLRECEIVER_H
+#define QABSTRACTXMLRECEIVER_H
+
+#include <QtCore/QVariant>
+#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);
+ 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 0000000000..3954a4f9c2
--- /dev/null
+++ b/src/xmlpatterns/api/qabstractxmlreceiver_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists 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/qdeviceresourceloader_p.h b/src/xmlpatterns/api/qdeviceresourceloader_p.h
new file mode 100644
index 0000000000..be88a76217
--- /dev/null
+++ b/src/xmlpatterns/api/qdeviceresourceloader_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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 <fenglich@trolltech.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 0000000000..05820a75b0
--- /dev/null
+++ b/src/xmlpatterns/api/qiodevicedelegate.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..bf4e882da1
--- /dev/null
+++ b/src/xmlpatterns/api/qiodevicedelegate_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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 0000000000..3ca0383c19
--- /dev/null
+++ b/src/xmlpatterns/api/qnetworkaccessdelegator.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include <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 0000000000..7b7c0a48e8
--- /dev/null
+++ b/src/xmlpatterns/api/qnetworkaccessdelegator_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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 <fenglich@trolltech.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/qreferencecountedvalue_p.h b/src/xmlpatterns/api/qreferencecountedvalue_p.h
new file mode 100644
index 0000000000..49437f2c04
--- /dev/null
+++ b/src/xmlpatterns/api/qreferencecountedvalue_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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 0000000000..9d43419310
--- /dev/null
+++ b/src/xmlpatterns/api/qresourcedelegator.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qresourcedelegator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/**
+ * Duplicated in qacceltreeresourceloader.cpp.
+ */
+static inline uint qHash(const QUrl &uri)
+{
+ return qHash(uri.toString());
+}
+
+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 0000000000..d0f832ea0a
--- /dev/null
+++ b/src/xmlpatterns/api/qresourcedelegator_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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 <fenglich@trolltech.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 0000000000..119a4b1e28
--- /dev/null
+++ b/src/xmlpatterns/api/qsimplexmlnodemodel.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+#include <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 0000000000..14e2faf3c4
--- /dev/null
+++ b/src/xmlpatterns/api/qsimplexmlnodemodel.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..4eee39ce74
--- /dev/null
+++ b/src/xmlpatterns/api/qsourcelocation.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..d970edd392
--- /dev/null
+++ b/src/xmlpatterns/api/qsourcelocation.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..8b29b3c4f7
--- /dev/null
+++ b/src/xmlpatterns/api/quriloader.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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(qVariantValue<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 0000000000..c5ba3754e8
--- /dev/null
+++ b/src/xmlpatterns/api/quriloader_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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 0000000000..076adc3e9a
--- /dev/null
+++ b/src/xmlpatterns/api/qvariableloader.cpp
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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(qVariantValue<QXmlQuery>(variant));
+ return variableQuery.d->expression()->staticType();
+ }
+ else
+ {
+ return makeGenericSequenceType(AtomicValue::qtToXDMType(qVariantValue<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(qVariantValue<QXmlQuery>(variant));
+
+ return variableQuery.d->expression()->evaluateSequence(DynamicContext::Ptr(new TemporaryTreesRedirectingContext(variableQuery.d->dynamicContext(), context)));
+ }
+
+ const QVariant v(qVariantValue<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(qVariantValue<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(qVariantValue<QXmlItem>(v1));
+ const QXmlItem i2(qVariantValue<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 0000000000..7c02d9f59b
--- /dev/null
+++ b/src/xmlpatterns/api/qvariableloader_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef PATTERNIST_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 0000000000..7e1c1f569c
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlformatter.cpp
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..a839751059
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlformatter.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..82350b2e1d
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlname.cpp
@@ -0,0 +1,511 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * 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 0000000000..f5dcddf912
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlname.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..2337f8d813
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlnamepool.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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()
+{
+}
+
+/*!
+ 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 0000000000..3c1e112114
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlnamepool.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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;
+}
+
+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:
+ friend class QXmlQueryPrivate;
+ friend class QXmlQuery;
+ friend class QXmlSerializerPrivate;
+ friend class QXmlName;
+ friend class QPatternistSDK::Global;
+ QExplicitlySharedDataPointer<QPatternist::NamePool> d;
+};
+
+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 0000000000..5f9d87d748
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlquery.cpp
@@ -0,0 +1,1179 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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{QtXmlPatterns Module#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
+
+ \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{QtXmlPatterns Module#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 = QXmlQueryPrivate::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(QXmlQueryPrivate::normalizeQueryURI(queryURI));
+ Q_ASSERT(canonicalURI.isValid());
+ Q_ASSERT(!canonicalURI.isRelative());
+ Q_ASSERT(baseURI.isValid() || baseURI.isEmpty());
+
+ d->queryURI = QXmlQueryPrivate::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(qVariantFromValue(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(qVariantFromValue(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);
+}
+
+/*!
+ 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(qVariantFromValue(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 0000000000..138819c087
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlquery.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 VariableLoader;
+};
+
+class Q_XMLPATTERNS_EXPORT QXmlQuery
+{
+public:
+ enum QueryLanguage
+ {
+ XQuery10 = 1,
+ XSLT20 = 2
+ };
+
+ 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);
+
+ 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::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 0000000000..c8ed4412ca
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlquery_p.h
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QXMLQUERY_P_H
+#define QXMLQUERY_P_H
+
+#include <QAbstractMessageHandler>
+#include <QAbstractUriResolver>
+#include <QCoreApplication>
+#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::XQuery10)
+ m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d);
+ else
+ {
+ Q_ASSERT(queryLanguage == QXmlQuery::XSLT20);
+ m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(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));
+
+ 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;
+ }
+
+
+ static inline QUrl 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;
+ }
+
+ 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;
+ }
+
+ 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;
+};
+
+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 0000000000..a2253c98e8
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlresultitems.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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.
+
+ \sa QXmlItem::isNode(), QXmlItem::isAtomicValue(), QXmlNodeModelIndex
+ */
+
+/*!
+ Constructs an instance of QXmlResultItems.
+ */
+QXmlResultItems::QXmlResultItems() : d_ptr(new QXmlResultItemsPrivate())
+{
+}
+
+/*!
+ Destroys this instance of QXmlResultItems.
+ */
+QXmlResultItems::~QXmlResultItems()
+{
+ delete d_ptr;
+}
+
+/*!
+ 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 0000000000..aeb7d2c66d
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlresultitems.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLRESULTITEMS
+#define QXMLRESULTITEMS
+
+#include <QtCore/QString>
+
+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)
+ 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 0000000000..af3e2d3314
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlresultitems_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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/qxmlserializer.cpp b/src/xmlpatterns/api/qxmlserializer.cpp
new file mode 100644
index 0000000000..0c2f92dad9
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlserializer.cpp
@@ -0,0 +1,653 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..a24b42bc0b
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlserializer.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..0bdff216f8
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlserializer_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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 0000000000..2573a26626
--- /dev/null
+++ b/src/xmlpatterns/common.pri
@@ -0,0 +1,17 @@
+# 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/type \
+ $$PWD/utils
+
+DEPENDPATH += $$INCLUDEPATH
+
diff --git a/src/xmlpatterns/data/data.pri b/src/xmlpatterns/data/data.pri
new file mode 100644
index 0000000000..99591d488e
--- /dev/null
+++ b/src/xmlpatterns/data/data.pri
@@ -0,0 +1,78 @@
+HEADERS += $$PWD/qabstractdatetime_p.h \
+ $$PWD/qabstractduration_p.h \
+ $$PWD/qabstractfloatcasters_p.h \
+ $$PWD/qabstractfloat_p.h \
+ $$PWD/qabstractfloatmathematician_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/qdate_p.h \
+ $$PWD/qschemadatetime_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/qgyear_p.h \
+ $$PWD/qgyearmonth_p.h \
+ $$PWD/qhexbinary_p.h \
+ $$PWD/qinteger_p.h \
+ $$PWD/qitem_p.h \
+ $$PWD/qnodebuilder_p.h \
+ $$PWD/qschemanumeric_p.h \
+ $$PWD/qqnamevalue_p.h \
+ $$PWD/qresourceloader_p.h \
+ $$PWD/qsorttuple.cpp \
+ $$PWD/qschematime_p.h \
+ $$PWD/quntypedatomic_p.h \
+ $$PWD/qvalidationerror_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/qdate.cpp \
+ $$PWD/qschemadatetime.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/qschemanumeric.cpp \
+ $$PWD/qqnamevalue.cpp \
+ $$PWD/qresourceloader.cpp \
+ $$PWD/qsorttuple.cpp \
+ $$PWD/qschematime.cpp \
+ $$PWD/quntypedatomic.cpp \
+ $$PWD/qvalidationerror.cpp \
+ $$PWD/qyearmonthduration.cpp
diff --git a/src/xmlpatterns/data/qabstractdatetime.cpp b/src/xmlpatterns/data/qabstractdatetime.cpp
new file mode 100644
index 0000000000..819f033bbf
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractdatetime.cpp
@@ -0,0 +1,400 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "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'));
+ 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 0000000000..2786adfad3
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractdatetime_p.h
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..4f34ff31a7
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractduration.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "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 0000000000..af2a985355
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractduration_p.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..b6226b5568
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloat.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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
+ {
+ /* Preferrably, 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.left(1);
+ 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 0000000000..61ec9c152d
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloat_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..bf53fa4d3b
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatcasters.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * 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
+{
+ if(from.template as<AtomicValue>()->evaluateEBV(context))
+ return isDouble ? toItem(CommonValues::DoubleOne) : toItem(CommonValues::FloatOne);
+ else
+ return isDouble ? 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 0000000000..36a5116429
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatcasters_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.com>
+ */
+ typedef StringToAbstractFloatCaster<false> StringToFloatCaster;
+
+ /**
+ * @short Casts a value of type @c xs:boolean to @c xs:double.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ typedef BooleanToAbstractFloatCaster<true> BooleanToDoubleCaster;
+
+ /**
+ * @short Casts a value of type @c xs:boolean to @c xs:float.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <fenglich@trolltech.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 0000000000..767fa47bea
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatmathematician.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * @file
+ * @short This file is included by 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 0000000000..eb9eb11a32
--- /dev/null
+++ b/src/xmlpatterns/data/qabstractfloatmathematician_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..0c6288baad
--- /dev/null
+++ b/src/xmlpatterns/data/qanyuri.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..32726359dd
--- /dev/null
+++ b/src/xmlpatterns/data/qanyuri_p.h
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..a087725558
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccaster.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..6680dc58c4
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccaster_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..893dce4d16
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccasters.cpp
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..888ad326f4
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccasters_p.h
@@ -0,0 +1,705 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..34395facdb
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparator.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..2ec7815d63
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparator_p.h
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..af28b42c98
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparators.cpp
@@ -0,0 +1,386 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..82a60680fc
--- /dev/null
+++ b/src/xmlpatterns/data/qatomiccomparators_p.h
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..816f731457
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematician.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..37d0cc5e5c
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematician_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..bd138a8e16
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematicians.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..7bbdaef8d3
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicmathematicians_p.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..5e92e946d4
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicstring.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..bbdc66dc93
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicstring_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..a68643f27d
--- /dev/null
+++ b/src/xmlpatterns/data/qatomicvalue.cpp
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 defintion 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 qVariantFromValue(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.type())
+ {
+ 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 QVariant::Double:
+ return Item(Double::fromValue(value.toDouble()));
+ default:
+ {
+ 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(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 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 0000000000..0f805c04fe
--- /dev/null
+++ b/src/xmlpatterns/data/qbase64binary.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..9eaa23b80c
--- /dev/null
+++ b/src/xmlpatterns/data/qbase64binary_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..e87d6c231a
--- /dev/null
+++ b/src/xmlpatterns/data/qboolean.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..10b1515e66
--- /dev/null
+++ b/src/xmlpatterns/data/qboolean_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..07a273d2be
--- /dev/null
+++ b/src/xmlpatterns/data/qcommonvalues.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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(QString(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 0000000000..6b9cf64518
--- /dev/null
+++ b/src/xmlpatterns/data/qcommonvalues_p.h
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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/qdate.cpp b/src/xmlpatterns/data/qdate.cpp
new file mode 100644
index 0000000000..d451e29763
--- /dev/null
+++ b/src/xmlpatterns/data/qdate.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..e804bfa326
--- /dev/null
+++ b/src/xmlpatterns/data/qdate_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..3555e59180
--- /dev/null
+++ b/src/xmlpatterns/data/qdaytimeduration.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractdatetime_p.h"
+#include "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 0000000000..f6a31176da
--- /dev/null
+++ b/src/xmlpatterns/data/qdaytimeduration_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..05f84b4ebc
--- /dev/null
+++ b/src/xmlpatterns/data/qdecimal.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..2552b21c8a
--- /dev/null
+++ b/src/xmlpatterns/data/qdecimal_p.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Decimal_H
+#define Patternist_Decimal_H
+
+#include "qschemanumeric_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * Defined in QtCore's qlocale.cpp.
+ */
+extern 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 <fenglich@trolltech.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 0000000000..4a394b3e84
--- /dev/null
+++ b/src/xmlpatterns/data/qderivedinteger_p.h
@@ -0,0 +1,624 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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(formatData(static_cast<xsInteger>(num)))
+ .arg(formatType(np, itemType()))
+ .arg(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(formatData(static_cast<xsInteger>(num)))
+ .arg(formatType(np, itemType()))
+ .arg(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 0000000000..a9d4f16a33
--- /dev/null
+++ b/src/xmlpatterns/data/qderivedstring_p.h
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c36adc409d
--- /dev/null
+++ b/src/xmlpatterns/data/qduration.cpp
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractdatetime_p.h"
+#include "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 0000000000..fe58317af6
--- /dev/null
+++ b/src/xmlpatterns/data/qduration_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..e2bd2e5594
--- /dev/null
+++ b/src/xmlpatterns/data/qgday.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..1d6949474e
--- /dev/null
+++ b/src/xmlpatterns/data/qgday_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..ddac353f43
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonth.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..9b1a2c8634
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonth_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d7df81b570
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonthday.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..dbb507dd3a
--- /dev/null
+++ b/src/xmlpatterns/data/qgmonthday_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..a58e1c1be9
--- /dev/null
+++ b/src/xmlpatterns/data/qgyear.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..eef81dc4c8
--- /dev/null
+++ b/src/xmlpatterns/data/qgyear_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..f8f21318cd
--- /dev/null
+++ b/src/xmlpatterns/data/qgyearmonth.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..134c795e2a
--- /dev/null
+++ b/src/xmlpatterns/data/qgyearmonth_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..00028e7929
--- /dev/null
+++ b/src/xmlpatterns/data/qhexbinary.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..e1a76396a6
--- /dev/null
+++ b/src/xmlpatterns/data/qhexbinary_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0a8c9cc9df
--- /dev/null
+++ b/src/xmlpatterns/data/qinteger.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..c70f04b482
--- /dev/null
+++ b/src/xmlpatterns/data/qinteger_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..eaf47ef589
--- /dev/null
+++ b/src/xmlpatterns/data/qitem.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "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 0000000000..987a1c2240
--- /dev/null
+++ b/src/xmlpatterns/data/qitem_p.h
@@ -0,0 +1,542 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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.
+ * @author Trolltech
+ */
+
+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 <fenglich@trolltech.com>
+ */
+ class AtomicValue : public QSharedData
+ , public CppCastingHelper<AtomicValue>
+ {
+ public:
+ virtual ~AtomicValue();
+
+ /**
+ * A smart pointer wrapping AtomicValue instances.
+ */
+ typedef QExplicitlySharedDataPointer<AtomicValue> Ptr;
+
+ /**
+ * 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 <fenglich@trolltech.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 0000000000..c848216c54
--- /dev/null
+++ b/src/xmlpatterns/data/qnodebuilder.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..4057e5e90d
--- /dev/null
+++ b/src/xmlpatterns/data/qnodebuilder_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..b44f58beb9
--- /dev/null
+++ b/src/xmlpatterns/data/qnodemodel.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "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 0000000000..ae93cd2f8d
--- /dev/null
+++ b/src/xmlpatterns/data/qqnamevalue.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..d038f7426e
--- /dev/null
+++ b/src/xmlpatterns/data/qqnamevalue_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..8633381a9d
--- /dev/null
+++ b/src/xmlpatterns/data/qresourceloader.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+
+#include "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 0000000000..c11304fa87
--- /dev/null
+++ b/src/xmlpatterns/data/qresourceloader_p.h
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 can't 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 0000000000..425af7db6b
--- /dev/null
+++ b/src/xmlpatterns/data/qschemadatetime.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..c974242444
--- /dev/null
+++ b/src/xmlpatterns/data/qschemadatetime_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..4f42db955d
--- /dev/null
+++ b/src/xmlpatterns/data/qschemanumeric.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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
+ * @short 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 0000000000..8654b5741a
--- /dev/null
+++ b/src/xmlpatterns/data/qschemanumeric_p.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..cd6f17e4dd
--- /dev/null
+++ b/src/xmlpatterns/data/qschematime.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..a5a9549898
--- /dev/null
+++ b/src/xmlpatterns/data/qschematime_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 orignally called Time.h, but this
+ * clashed with a system header on MinGW.
+ *
+ * @author Frans Englich <fenglich@trolltech.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 0000000000..4e9fdfe5ff
--- /dev/null
+++ b/src/xmlpatterns/data/qsequencereceiver.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..e508acb8c0
--- /dev/null
+++ b/src/xmlpatterns/data/qsequencereceiver_p.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..93f9b30215
--- /dev/null
+++ b/src/xmlpatterns/data/qsorttuple.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..fa4fa9c295
--- /dev/null
+++ b/src/xmlpatterns/data/qsorttuple_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..6b398272eb
--- /dev/null
+++ b/src/xmlpatterns/data/quntypedatomic.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "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 0000000000..4f578e8a15
--- /dev/null
+++ b/src/xmlpatterns/data/quntypedatomic_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..1a6063b7e3
--- /dev/null
+++ b/src/xmlpatterns/data/qvalidationerror.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "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 0000000000..e525a54414
--- /dev/null
+++ b/src/xmlpatterns/data/qvalidationerror_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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/qyearmonthduration.cpp b/src/xmlpatterns/data/qyearmonthduration.cpp
new file mode 100644
index 0000000000..45bab3d35c
--- /dev/null
+++ b/src/xmlpatterns/data/qyearmonthduration.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..59996f09de
--- /dev/null
+++ b/src/xmlpatterns/data/qyearmonthduration_p.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..fabbad32c6
--- /dev/null
+++ b/src/xmlpatterns/documentationGroups.dox
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+/**
+ * @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 <fenglich@trolltech.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 <fenglich@trolltech.com>
+ */
+
+ /**
+ * @short Various classes that contains small utility functions.
+ *
+ * @defgroup Patternist Utility Classes
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+
+ /**
+ * @short Classes for the type system in the XQuery & XSL-T language.
+ *
+ * @defgroup Patternist_types Type system
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+
+ /**
+ * @defgroup Patternist_xdm XQuery/XPath Data Model
+ * @author Frans Englich <fenglich@trolltech.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 <fenglich@trolltech.com>
+ */
+}
diff --git a/src/xmlpatterns/environment/createReportContext.sh b/src/xmlpatterns/environment/createReportContext.sh
new file mode 100755
index 0000000000..dcbf9ea57e
--- /dev/null
+++ b/src/xmlpatterns/environment/createReportContext.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+# 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 0000000000..e648c56923
--- /dev/null
+++ b/src/xmlpatterns/environment/createReportContext.xsl
@@ -0,0 +1,554 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Patternist project on Trolltech 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+***************************************************************************
+*/
+-->
+
+<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) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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
+ {
+<!-- 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 0000000000..b8a2b65877
--- /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 0000000000..117988f80f
--- /dev/null
+++ b/src/xmlpatterns/environment/qcurrentitemcontext.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..44ad24530d
--- /dev/null
+++ b/src/xmlpatterns/environment/qcurrentitemcontext_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..197dc0d261
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..c269a90bad
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..51aeee8f51
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingstaticcontext.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* 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 0000000000..527cda2790
--- /dev/null
+++ b/src/xmlpatterns/environment/qdelegatingstaticcontext_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..8276b77626
--- /dev/null
+++ b/src/xmlpatterns/environment/qdynamiccontext.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..61b0f56e71
--- /dev/null
+++ b/src/xmlpatterns/environment/qdynamiccontext_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..1ce3e0fe4c
--- /dev/null
+++ b/src/xmlpatterns/environment/qfocus.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..08b9d26fe0
--- /dev/null
+++ b/src/xmlpatterns/environment/qfocus_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..86db046f68
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericdynamiccontext.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonvalues_p.h"
+#include "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 0000000000..619c54f4fa
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericdynamiccontext_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..61a979f97f
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericstaticcontext.cpp
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+
+/* 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 0000000000..42204eab5d
--- /dev/null
+++ b/src/xmlpatterns/environment/qgenericstaticcontext_p.h
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..909b471235
--- /dev/null
+++ b/src/xmlpatterns/environment/qreceiverdynamiccontext.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..b4bb9c1d63
--- /dev/null
+++ b/src/xmlpatterns/environment/qreceiverdynamiccontext_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..9704a54d56
--- /dev/null
+++ b/src/xmlpatterns/environment/qreportcontext.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "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;
+ }
+
+ 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 0000000000..bea2a97c17
--- /dev/null
+++ b/src/xmlpatterns/environment/qreportcontext_p.h
@@ -0,0 +1,2460 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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
+ {
+
+ /**
+ * 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 0000000000..fbed9cd604
--- /dev/null
+++ b/src/xmlpatterns/environment/qstackcontextbase.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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 0000000000..ac1f038f40
--- /dev/null
+++ b/src/xmlpatterns/environment/qstackcontextbase_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..280763ae81
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticbaseuricontext.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..db0d85cc36
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticbaseuricontext_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c437ba100e
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..4fbeff748d
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..69067deb67
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcontext.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonnamespaces_p.h"
+#include "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 0000000000..bda7a99c0c
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcontext_p.h
@@ -0,0 +1,299 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..31bb40e315
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcurrentcontext.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..137463e787
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticcurrentcontext_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..bb0fd6262d
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticfocuscontext.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..69bb598854
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticfocuscontext_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..10344bdc76
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticnamespacecontext.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..705c7186ea
--- /dev/null
+++ b/src/xmlpatterns/environment/qstaticnamespacecontext_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..81c3994753
--- /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 0000000000..3ffd6b8b61
--- /dev/null
+++ b/src/xmlpatterns/expr/qandexpression.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "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 0000000000..c83d30155f
--- /dev/null
+++ b/src/xmlpatterns/expr/qandexpression_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..95f4fdf377
--- /dev/null
+++ b/src/xmlpatterns/expr/qapplytemplate.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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);
+ }
+ else
+ 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 0000000000..ef2424c4f6
--- /dev/null
+++ b/src/xmlpatterns/expr/qapplytemplate_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..6eb683f046
--- /dev/null
+++ b/src/xmlpatterns/expr/qargumentreference.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "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 0000000000..a29ae087a9
--- /dev/null
+++ b/src/xmlpatterns/expr/qargumentreference_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..f8cde0c987
--- /dev/null
+++ b/src/xmlpatterns/expr/qarithmeticexpression.cpp
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "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 <fenglich@trolltech.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 0000000000..335635279a
--- /dev/null
+++ b/src/xmlpatterns/expr/qarithmeticexpression_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 substraction.
+ *
+ *
+ * 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 <fenglich@trolltech.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 0000000000..4cc357a078
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributeconstructor.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "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 0000000000..ac42e7b872
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributeconstructor_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..abca6b9496
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributenamevalidator.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..3e2c43b9ff
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributenamevalidator_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..5297dab87d
--- /dev/null
+++ b/src/xmlpatterns/expr/qaxisstep.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..620824bb34
--- /dev/null
+++ b/src/xmlpatterns/expr/qaxisstep_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c9f78a6f80
--- /dev/null
+++ b/src/xmlpatterns/expr/qcachecells_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..6d3f052393
--- /dev/null
+++ b/src/xmlpatterns/expr/qcallsite.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..558e83cba5
--- /dev/null
+++ b/src/xmlpatterns/expr/qcallsite_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..8c8bfdf394
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltargetdescription.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..1e44980a76
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltargetdescription_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..d0ae01741f
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltemplate.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "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 0000000000..c49ec21a79
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltemplate_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..8ba015b7fc
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastableas.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..b1b2ecfd7f
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastableas_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..b8771ba870
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastas.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..8f4690ec35
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastas_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..9e96fd8cf6
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastingplatform.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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));
+
+ 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);
+
+ 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
+{
+ 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, static_cast<const TSubClass *>(this));
+ }
+ else
+ castImpossible = true;
+
+ return AtomicCaster::Ptr();
+ }
+
+ const AtomicCaster::Ptr caster(static_cast<const AtomicType *>(sourceType.data())->accept(locator, static_cast<const TSubClass *>(this)));
+ 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, static_cast<const TSubClass *>(this));
+ }
+ 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 0000000000..458e9ebc01
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastingplatform_p.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CastingPlatform_H
+#define Patternist_CastingPlatform_H
+
+#include "qatomiccaster_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+#include "qvalidationerror_p.h"
+#include "qatomiccasterlocator_p.h"
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qschematypefactory_p.h"
+#include "qpatternistlocale_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.
+ *
+ * @author Frans Englich <fenglich@trolltech.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.
+ */
+ AtomicCaster::Ptr locateCaster(const ItemType::Ptr &sourceType,
+ const ReportContext::Ptr &context,
+ bool &castImpossible) 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 0000000000..2d8e49abc3
--- /dev/null
+++ b/src/xmlpatterns/expr/qcollationchecker.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..b79f0e81bf
--- /dev/null
+++ b/src/xmlpatterns/expr/qcollationchecker_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c953322bb7
--- /dev/null
+++ b/src/xmlpatterns/expr/qcombinenodes.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..9d1dc8743e
--- /dev/null
+++ b/src/xmlpatterns/expr/qcombinenodes_p.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..f8f5688818
--- /dev/null
+++ b/src/xmlpatterns/expr/qcommentconstructor.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..25036416c1
--- /dev/null
+++ b/src/xmlpatterns/expr/qcommentconstructor_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..5d1090518d
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomparisonplatform.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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 0000000000..fb088a884d
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomparisonplatform_p.h
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..f782d0481c
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..48e79f566a
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..769dd4dec3
--- /dev/null
+++ b/src/xmlpatterns/expr/qcontextitem.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..42df859fa6
--- /dev/null
+++ b/src/xmlpatterns/expr/qcontextitem_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..448ce5e943
--- /dev/null
+++ b/src/xmlpatterns/expr/qcopyof.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..64b0f985dc
--- /dev/null
+++ b/src/xmlpatterns/expr/qcopyof_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..8ab3ea596b
--- /dev/null
+++ b/src/xmlpatterns/expr/qcurrentitemstore.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..6223b2f1f7
--- /dev/null
+++ b/src/xmlpatterns/expr/qcurrentitemstore_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..3c4a14732b
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentconstructor.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..bc74a27323
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentconstructor_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..37df40acaf
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpatternistlocale_p.h"
+
+#include "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 0000000000..2053a05e1c
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..9dbedf2891
--- /dev/null
+++ b/src/xmlpatterns/expr/qdynamiccontextstore.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..b971f96f26
--- /dev/null
+++ b/src/xmlpatterns/expr/qdynamiccontextstore_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..57da1aca16
--- /dev/null
+++ b/src/xmlpatterns/expr/qelementconstructor.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..7eacb2b7ee
--- /dev/null
+++ b/src/xmlpatterns/expr/qelementconstructor_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d66f167c22
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptycontainer.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..de42e9b985
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptycontainer_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..ef8130de72
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptysequence.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonvalues_p.h"
+#include "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 0000000000..f5de6db135
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptysequence_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..5e0826d80f
--- /dev/null
+++ b/src/xmlpatterns/expr/qevaluationcache.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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 0000000000..7daed76c1b
--- /dev/null
+++ b/src/xmlpatterns/expr/qevaluationcache_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..493086b266
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpression.cpp
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "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 0000000000..5eb63deb44
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpression_p.h
@@ -0,0 +1,909 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..5ab1a0fa2e
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressiondispatch_p.h
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.com>
+ */
+ class ExpressionVisitorResult : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionVisitorResult> Ptr;
+ ExpressionVisitorResult() {}
+ virtual ~ExpressionVisitorResult() {}
+ };
+
+ /**
+ * @ingroup Patternist_expr_dispatch
+ * @author Frans Englich <fenglich@trolltech.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 0000000000..ec86be04db
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionfactory.cpp
@@ -0,0 +1,480 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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::XQuery10)
+ {
+ return createExpression(Tokenizer::Ptr(new XQueryTokenizer(expr, queryURI)),
+ context,
+ lang,
+ requiredType,
+ queryURI,
+ initialTemplateName);
+ }
+ else
+ {
+ Q_ASSERT(lang == QXmlQuery::XSLT20);
+ QByteArray query(expr.toUtf8());
+ QBuffer buffer(&query);
+ buffer.open(QIODevice::ReadOnly);
+
+ return createExpression(&buffer,
+ 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::XQuery10)
+ {
+
+ tokenizer = Tokenizer::Ptr(new XQueryTokenizer(QString::fromUtf8(device->readAll()), queryURI));
+ }
+ else
+ {
+ Q_ASSERT(lang == QXmlQuery::XSLT20);
+ tokenizer = Tokenizer::Ptr(new XSLTTokenizer(device, queryURI, context, context->namePool()));
+ }
+
+ 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 0000000000..c06a7e5710
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionfactory_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d052400cbf
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionsequence.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..7b5ad69a50
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionsequence_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c327971fbf
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionvariablereference.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#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 0000000000..a7d63e76bc
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionvariablereference_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..ac7a9c0bc3
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariableloader.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..4eacd99346
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariableloader_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..bbbef86722
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariablereference.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "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 0000000000..928af9d57f
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariablereference_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..03b8bad51b
--- /dev/null
+++ b/src/xmlpatterns/expr/qfirstitempredicate.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..7e3f3101db
--- /dev/null
+++ b/src/xmlpatterns/expr/qfirstitempredicate_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..cf9e634b3f
--- /dev/null
+++ b/src/xmlpatterns/expr/qforclause.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..d1cee33c27
--- /dev/null
+++ b/src/xmlpatterns/expr/qforclause_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..b564c84ef0
--- /dev/null
+++ b/src/xmlpatterns/expr/qgeneralcomparison.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "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 0000000000..9ff2435f9f
--- /dev/null
+++ b/src/xmlpatterns/expr/qgeneralcomparison_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..839a5f8c0f
--- /dev/null
+++ b/src/xmlpatterns/expr/qgenericpredicate.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloat_p.h"
+#include "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 0000000000..fe0eda68a5
--- /dev/null
+++ b/src/xmlpatterns/expr/qgenericpredicate_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..454df9a6d1
--- /dev/null
+++ b/src/xmlpatterns/expr/qifthenclause.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..26aabb0df3
--- /dev/null
+++ b/src/xmlpatterns/expr/qifthenclause_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..41f130538c
--- /dev/null
+++ b/src/xmlpatterns/expr/qinstanceof.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "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 0000000000..3d6b53ce77
--- /dev/null
+++ b/src/xmlpatterns/expr/qinstanceof_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..5dc5148d65
--- /dev/null
+++ b/src/xmlpatterns/expr/qletclause.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "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 0000000000..c9c0180e27
--- /dev/null
+++ b/src/xmlpatterns/expr/qletclause_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..2b1bdde9f2
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteral.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..3da667dc54
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteral_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..15c25ca828
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteralsequence.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..e5b4556a41
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteralsequence_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d596e0f600
--- /dev/null
+++ b/src/xmlpatterns/expr/qnamespaceconstructor.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..0807c148de
--- /dev/null
+++ b/src/xmlpatterns/expr/qnamespaceconstructor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..2e9f71d097
--- /dev/null
+++ b/src/xmlpatterns/expr/qncnameconstructor.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..8632a245f7
--- /dev/null
+++ b/src/xmlpatterns/expr/qncnameconstructor_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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, is %2 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 0000000000..2b70bf9857
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodecomparison.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "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 0000000000..82a7d07c1c
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodecomparison_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0f0d9a24d8
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodesort.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..225fbb9a2f
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodesort_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..195c512188
--- /dev/null
+++ b/src/xmlpatterns/expr/qoperandsiterator_p.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..aafe660e7e
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizationpasses.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..178ca27524
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizationpasses_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..e0d0ff6c5d
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerblocks.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonnamespaces_p.h"
+
+#include "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 0000000000..123a65502b
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerblocks_p.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..5e470ecc34
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerframework.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..6a674836ac
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerframework_p.h
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..af1d52b2fc
--- /dev/null
+++ b/src/xmlpatterns/expr/qorderby.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..d817f8eb4e
--- /dev/null
+++ b/src/xmlpatterns/expr/qorderby_p.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..58c05273f3
--- /dev/null
+++ b/src/xmlpatterns/expr/qorexpression.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..06471ed693
--- /dev/null
+++ b/src/xmlpatterns/expr/qorexpression_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..74de69cdc7
--- /dev/null
+++ b/src/xmlpatterns/expr/qpaircontainer.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..0311c890bb
--- /dev/null
+++ b/src/xmlpatterns/expr/qpaircontainer_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..f75aefd88f
--- /dev/null
+++ b/src/xmlpatterns/expr/qparentnodeaxis.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "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 0000000000..6c1c5ddd08
--- /dev/null
+++ b/src/xmlpatterns/expr/qparentnodeaxis_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..33bfa0f840
--- /dev/null
+++ b/src/xmlpatterns/expr/qpath.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..cc2d5d5ed2
--- /dev/null
+++ b/src/xmlpatterns/expr/qpath_p.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c0316c9b18
--- /dev/null
+++ b/src/xmlpatterns/expr/qpositionalvariablereference.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..2bf933b937
--- /dev/null
+++ b/src/xmlpatterns/expr/qpositionalvariablereference_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..379d9f73f1
--- /dev/null
+++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "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 0000000000..64a9f80b0d
--- /dev/null
+++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..a0cc85b336
--- /dev/null
+++ b/src/xmlpatterns/expr/qqnameconstructor.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..95ea5b9678
--- /dev/null
+++ b/src/xmlpatterns/expr/qqnameconstructor_p.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d8037df5c4
--- /dev/null
+++ b/src/xmlpatterns/expr/qquantifiedexpression.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..acdfc15255
--- /dev/null
+++ b/src/xmlpatterns/expr/qquantifiedexpression_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..2313880bcb
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangeexpression.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "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 0000000000..7a87514ab6
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangeexpression_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..057fa38fce
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangevariablereference.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..97c2b72de8
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangevariablereference_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..9c3ee82054
--- /dev/null
+++ b/src/xmlpatterns/expr/qreturnorderby.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..1c2d9528d3
--- /dev/null
+++ b/src/xmlpatterns/expr/qreturnorderby_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..e2006b02ce
--- /dev/null
+++ b/src/xmlpatterns/expr/qsimplecontentconstructor.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..ba9b86d232
--- /dev/null
+++ b/src/xmlpatterns/expr/qsimplecontentconstructor_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..a0a0c01a33
--- /dev/null
+++ b/src/xmlpatterns/expr/qsinglecontainer.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..0d9f97e617
--- /dev/null
+++ b/src/xmlpatterns/expr/qsinglecontainer_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..fca711fe3b
--- /dev/null
+++ b/src/xmlpatterns/expr/qsourcelocationreflection.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..79faeef7a0
--- /dev/null
+++ b/src/xmlpatterns/expr/qsourcelocationreflection_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0abd6a819d
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticbaseuristore.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..3d7573f77f
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticbaseuristore_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..8f6f025aa3
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..168b1cf5ca
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..1b9d904140
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplate.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..d4f37a7161
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplate_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..227feba347
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateinvoker.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..84908f10af
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateinvoker_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..23de18fccd
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatemode.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..16d09e2916
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatemode_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..3b295e9cea
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateparameterreference.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..594253b8e1
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateparameterreference_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..6ea98669db
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatepattern_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..085a909a11
--- /dev/null
+++ b/src/xmlpatterns/expr/qtextnodeconstructor.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..46c92acc7d
--- /dev/null
+++ b/src/xmlpatterns/expr/qtextnodeconstructor_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..13d2946f10
--- /dev/null
+++ b/src/xmlpatterns/expr/qtreatas.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..ce43e9a168
--- /dev/null
+++ b/src/xmlpatterns/expr/qtreatas_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..de4ba787e4
--- /dev/null
+++ b/src/xmlpatterns/expr/qtriplecontainer.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..84627f84fc
--- /dev/null
+++ b/src/xmlpatterns/expr/qtriplecontainer_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..34e12e5cdc
--- /dev/null
+++ b/src/xmlpatterns/expr/qtruthpredicate.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..06189974af
--- /dev/null
+++ b/src/xmlpatterns/expr/qtruthpredicate_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..df30241bec
--- /dev/null
+++ b/src/xmlpatterns/expr/qunaryexpression.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..70a29ad3d1
--- /dev/null
+++ b/src/xmlpatterns/expr/qunaryexpression_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..3a1d7cafaf
--- /dev/null
+++ b/src/xmlpatterns/expr/qunlimitedcontainer.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..6c9917ec23
--- /dev/null
+++ b/src/xmlpatterns/expr/qunlimitedcontainer_p.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..2b98f99624
--- /dev/null
+++ b/src/xmlpatterns/expr/qunresolvedvariablereference.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..272b6543df
--- /dev/null
+++ b/src/xmlpatterns/expr/qunresolvedvariablereference_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..fe96b1eb41
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunction.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "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 0000000000..86d6648f81
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunction_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..ec88175ad3
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunctioncallsite.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..50ae8f490c
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunctioncallsite_p.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0184a47bdf
--- /dev/null
+++ b/src/xmlpatterns/expr/qvalidate.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "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 0000000000..cf1654dd0a
--- /dev/null
+++ b/src/xmlpatterns/expr/qvalidate_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..a0a88daaa9
--- /dev/null
+++ b/src/xmlpatterns/expr/qvaluecomparison.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..01663de4d1
--- /dev/null
+++ b/src/xmlpatterns/expr/qvaluecomparison_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c59f344e72
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariabledeclaration.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..efc5c570e5
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariabledeclaration_p.h
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0692a3e888
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariablereference.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..da8bfe6834
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariablereference_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..af8c4064a1
--- /dev/null
+++ b/src/xmlpatterns/expr/qwithparam_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..ef77c76c54
--- /dev/null
+++ b/src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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;
+
+ 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 0000000000..93d8e7454d
--- /dev/null
+++ b/src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..7add8605a3
--- /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 0000000000..6d901aa625
--- /dev/null
+++ b/src/xmlpatterns/functions/qabstractfunctionfactory.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpatternistlocale_p.h"
+
+#include "qabstractfunctionfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr AbstractFunctionFactory::createFunctionCall(const QXmlName name,
+ const Expression::List &args,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+{
+ const FunctionSignature::Ptr sign(retrieveFunctionSignature(context->namePool(), name));
+
+ if(!sign) /* The function doesn't exist(at least not in this factory). */
+ return Expression::Ptr();
+
+ /* May throw. */
+ verifyArity(sign, context, args.count(), r);
+
+ /* Ok, the function does exist and the arity is correct. */
+ return retrieveExpression(name, args, sign);
+}
+
+void AbstractFunctionFactory::verifyArity(const FunctionSignature::Ptr &s,
+ const StaticContext::Ptr &context,
+ const xsInteger arity,
+ const SourceLocationReflection *const r) const
+{
+ /* Same code in both branches, but more specific error messages in order
+ * to improve usability. */
+ if(s->maximumArguments() != FunctionSignature::UnlimitedArity &&
+ arity > s->maximumArguments())
+ {
+ context->error(QtXmlPatterns::tr("%1 takes at most %n argument(s). "
+ "%2 is therefore invalid.", 0, s->maximumArguments())
+ .arg(formatFunction(context->namePool(), s))
+ .arg(arity),
+ ReportContext::XPST0017,
+ r);
+ return;
+ }
+
+ if(arity < s->minimumArguments())
+ {
+ context->error(QtXmlPatterns::tr("%1 requires at least %n argument(s). "
+ "%2 is therefore invalid.", 0, s->minimumArguments())
+ .arg(formatFunction(context->namePool(), s))
+ .arg(arity),
+ ReportContext::XPST0017,
+ r);
+ return;
+ }
+}
+
+FunctionSignature::Hash AbstractFunctionFactory::functionSignatures() const
+{
+ return m_signatures;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qabstractfunctionfactory_p.h b/src/xmlpatterns/functions/qabstractfunctionfactory_p.h
new file mode 100644
index 0000000000..b988658fa4
--- /dev/null
+++ b/src/xmlpatterns/functions/qabstractfunctionfactory_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AbstractFunctionFactory_H
+#define Patternist_AbstractFunctionFactory_H
+
+#include "qcommonnamespaces_p.h"
+#include "qfunctionfactory_p.h"
+#include "qfunctionsignature_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Supplies convenience code for the function factories.
+ *
+ * @ingroup Patternist_functions
+ * @see XPath10CoreFunctions
+ * @see XPath20CoreFunctions
+ * @see XSLT10CoreFunctions
+ * @author Vincent Ricard <magic@magicninja.org>
+ */
+ class AbstractFunctionFactory : public FunctionFactory
+ {
+ public:
+ virtual Expression::Ptr createFunctionCall(const QXmlName name,
+ const Expression::List &arguments,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r);
+
+ virtual FunctionSignature::Hash functionSignatures() const;
+
+ protected:
+ /**
+ * This function is responsible for creating the actual Expression, corresponding
+ * to @p localName and the function signature @p sign. It is called by
+ * createFunctionCall(), once it have been determined the function actually
+ * exists and have the correct arity.
+ *
+ * This function will only be called for names in the @c fn namespace.
+ */
+ virtual Expression::Ptr retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const = 0;
+
+ inline
+ FunctionSignature::Ptr addFunction(const QXmlName::LocalNameCode localName,
+ const FunctionSignature::Arity minArgs,
+ const FunctionSignature::Arity maxArgs,
+ const SequenceType::Ptr &returnType,
+ const Expression::Properties props)
+ {
+ return addFunction(localName,
+ minArgs,
+ maxArgs,
+ returnType,
+ Expression::IDIgnorableExpression,
+ props);
+ }
+
+ FunctionSignature::Ptr addFunction(const QXmlName::LocalNameCode &localName,
+ const FunctionSignature::Arity minArgs,
+ const FunctionSignature::Arity maxArgs,
+ const SequenceType::Ptr &returnType,
+ const Expression::ID id = Expression::IDIgnorableExpression,
+ const Expression::Properties props = Expression::Properties(),
+ const StandardNamespaces::ID ns = StandardNamespaces::fn)
+ {
+ const QXmlName name(ns, localName);
+
+ const FunctionSignature::Ptr s(new FunctionSignature(name, minArgs, maxArgs,
+ returnType, props, id));
+
+ m_signatures.insert(name, s);
+ return s;
+ }
+
+ static inline QXmlName::LocalNameCode argument(const NamePool::Ptr &np, const char *const name)
+ {
+ return np->allocateLocalName(QLatin1String(name));
+ }
+
+ FunctionSignature::Hash m_signatures;
+
+ private:
+ /**
+ * @short Determines whether @p arity is a valid number of
+ * arguments for the function with signature @p sign.
+ *
+ * If it is not, a static error with error code ReportContext::XPST0017
+ * is issued via @p context.
+ */
+ void verifyArity(const FunctionSignature::Ptr &sign,
+ const StaticContext::Ptr &context,
+ const xsInteger arity,
+ const SourceLocationReflection *const r) const;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qaccessorfns.cpp b/src/xmlpatterns/functions/qaccessorfns.cpp
new file mode 100644
index 0000000000..8ff9ef415c
--- /dev/null
+++ b/src/xmlpatterns/functions/qaccessorfns.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+#include "qitem_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+
+#include "qaccessorfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item NodeNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(item)
+ {
+ const QXmlName name(item.asNode().name());
+
+ if(name.isNull())
+ return Item();
+ else
+ return toItem(QNameValue::fromValue(context->namePool(), name));
+ }
+ else
+ return Item();
+}
+
+Item NilledFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(item && item.asNode().kind() == QXmlNodeModelIndex::Element)
+ {
+ /* We have no access to the PSVI -- always return false. */
+ return CommonValues::BooleanFalse;
+ }
+ else
+ return Item();
+}
+
+Item StringFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(item)
+ return AtomicString::fromValue(item.stringValue());
+ else
+ return CommonValues::EmptyString;
+}
+
+Expression::Ptr StringFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+ if(me != this)
+ return me;
+
+ if(BuiltinTypes::xsString->xdtTypeMatches(m_operands.first()->staticType()->itemType()))
+ return m_operands.first(); /* No need for string(), it's already a string. */
+ else
+ return me;
+}
+
+Item BaseURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item node(m_operands.first()->evaluateSingleton(context));
+
+ if(node)
+ {
+ const QUrl base(node.asNode().baseUri());
+
+ if(base.isEmpty())
+ return Item();
+ else if(base.isValid())
+ {
+ Q_ASSERT_X(!base.isRelative(), Q_FUNC_INFO,
+ "The base URI must be absolute.");
+ return toItem(AnyURI::fromValue(base));
+ }
+ else
+ return Item();
+ }
+ else
+ return Item();
+}
+
+Item DocumentURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item node(m_operands.first()->evaluateSingleton(context));
+
+ if(node)
+ {
+ const QUrl documentURI(node.asNode().documentUri());
+
+ if(documentURI.isValid())
+ {
+ if(documentURI.isEmpty())
+ return Item();
+ else
+ {
+ Q_ASSERT_X(!documentURI.isRelative(), Q_FUNC_INFO,
+ "The document URI must be absolute.");
+ return toItem(AnyURI::fromValue(documentURI));
+ }
+ }
+ else
+ return Item();
+ }
+ else
+ return Item();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qaccessorfns_p.h b/src/xmlpatterns/functions/qaccessorfns_p.h
new file mode 100644
index 0000000000..61c986a941
--- /dev/null
+++ b/src/xmlpatterns/functions/qaccessorfns_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AccessorFNs_H
+#define Patternist_AccessorFNs_H
+
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#accessors">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 2 Accessors</a>.
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:node-name()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NodeNameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:nilled()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NilledFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:string()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class StringFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ };
+
+ /**
+ * @short Implements the function <tt>fn:base-uri()</tt>.
+ *
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class BaseURIFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:document-uri()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DocumentURIFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qaggregatefns.cpp b/src/xmlpatterns/functions/qaggregatefns.cpp
new file mode 100644
index 0000000000..99302ba4b5
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregatefns.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloat_p.h"
+#include "qarithmeticexpression_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qdecimal_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qinteger_p.h"
+#include "qoptimizerblocks_p.h"
+#include "qsequencefns_p.h"
+#include "quntypedatomicconverter_p.h"
+
+#include "qaggregatefns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item CountFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return Integer::fromValue(m_operands.first()->evaluateSequence(context)->count());
+}
+
+Expression::Ptr CountFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(*CommonSequenceTypes::EBV->itemType() == *reqType->itemType())
+ {
+ return ByIDCreator::create(IDExistsFN, operands(), context, this)->typeCheck(context, reqType);
+ }
+ else
+ return FunctionCall::typeCheck(context, reqType);
+}
+
+Expression::Ptr CountFN::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(FunctionCall::compress(context));
+ if(me != this)
+ return me;
+
+ const Cardinality card(m_operands.first()->staticType()->cardinality());
+ if(card.isExactlyOne())
+ return wrapLiteral(CommonValues::IntegerOne, context, this);
+ else if(card.isEmpty())
+ {
+ /* One might think that if the operand is (), that compress() would have
+ * evaluated us and therefore this line never be reached, but "()" can
+ * be combined with the DisableElimination flag. */
+ return wrapLiteral(CommonValues::IntegerZero, context, this);
+ }
+ else if(card.isExact())
+ return wrapLiteral(Integer::fromValue(card.minimum()), context, this);
+ else
+ return me;
+}
+
+Expression::Ptr AddingAggregate::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+ ItemType::Ptr t1(m_operands.first()->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1)
+ return me;
+ else if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::numeric == *t1)
+ return me;
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1))
+ {
+ m_operands.replace(0, Expression::Ptr(new UntypedAtomicConverter(m_operands.first(),
+ BuiltinTypes::xsDouble)));
+ t1 = m_operands.first()->staticType()->itemType();
+ }
+ else if(!BuiltinTypes::numeric->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1))
+ {
+ /* Translator, don't translate the type names. */
+ context->error(QtXmlPatterns::tr("The first argument to %1 cannot be "
+ "of type %2. It must be a numeric "
+ "type, xs:yearMonthDuration or "
+ "xs:dayTimeDuration.")
+ .arg(formatFunction(context->namePool(), signature()))
+ .arg(formatType(context->namePool(),
+ m_operands.first()->staticType())),
+ ReportContext::FORG0006, this);
+ }
+
+ if(!m_operands.first()->staticType()->cardinality().allowsMany())
+ return m_operands.first();
+
+ /* We know fetchMathematician won't attempt a rewrite of the operand, so this is safe. */
+ m_mather = ArithmeticExpression::fetchMathematician(m_operands.first(), m_operands.first(),
+ AtomicMathematician::Add, true, context,
+ this,
+ ReportContext::FORG0006);
+ return me;
+}
+
+Item AvgFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));
+ Item sum(it->next());
+
+ xsInteger count = 0;
+ while(sum)
+ {
+ ++count;
+ const Item next(it->next());
+ if(!next)
+ break;
+
+ sum = ArithmeticExpression::flexiblyCalculate(sum, AtomicMathematician::Add,
+ next, m_adder, context,
+ this,
+ ReportContext::FORG0006);
+ };
+
+ if(!sum)
+ return Item();
+
+ /* Note that we use the same m_mather which was used for adding,
+ * can be worth to think about. */
+ return ArithmeticExpression::flexiblyCalculate(sum, AtomicMathematician::Div,
+ Integer::fromValue(count),
+ m_divider, context,
+ this,
+ ReportContext::FORG0006);
+}
+
+Expression::Ptr AvgFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+ ItemType::Ptr t1(m_operands.first()->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1)
+ return me;
+ else if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::numeric == *t1)
+ return me;
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1))
+ {
+ m_operands.replace(0, Expression::Ptr(new UntypedAtomicConverter(m_operands.first(),
+ BuiltinTypes::xsDouble)));
+ t1 = m_operands.first()->staticType()->itemType();
+ }
+ else if(!BuiltinTypes::numeric->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1))
+ {
+ /* Translator, don't translate the type names. */
+ context->error(QtXmlPatterns::tr("The first argument to %1 cannot be "
+ "of type %2. It must be of type %3, "
+ "%4, or %5.")
+ .arg(signature())
+ .arg(formatType(context->namePool(), m_operands.first()->staticType()))
+ .arg(formatType(context->namePool(), BuiltinTypes::numeric))
+ .arg(formatType(context->namePool(), BuiltinTypes::xsYearMonthDuration))
+ .arg(formatType(context->namePool(), BuiltinTypes::xsDayTimeDuration)),
+ ReportContext::FORG0006, this);
+ }
+
+ if(!m_operands.first()->staticType()->cardinality().allowsMany())
+ return m_operands.first();
+
+ /* We use CommonValues::IntegerOne here because it is an arbitrary Expression
+ * of type xs:integer */
+ Expression::Ptr op2(wrapLiteral(CommonValues::IntegerOne, context, this));
+ m_adder = ArithmeticExpression::fetchMathematician(m_operands.first(), m_operands.first(),
+ AtomicMathematician::Add, true, context, this);
+ m_divider = ArithmeticExpression::fetchMathematician(m_operands.first(), op2,
+ AtomicMathematician::Div, true, context, this);
+ return me;
+}
+
+SequenceType::Ptr AvgFN::staticType() const
+{
+ const SequenceType::Ptr opt(m_operands.first()->staticType());
+ ItemType::Ptr t(opt->itemType());
+
+ if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t))
+ t = BuiltinTypes::xsDouble; /* xsUntypedAtomics are converted to xsDouble. */
+ else if(BuiltinTypes::xsInteger->xdtTypeMatches(t))
+ t = BuiltinTypes::xsDecimal;
+
+ /* else, it means the type is xsDayTimeDuration, xsYearMonthDuration,
+ * xsDouble, xsFloat or xsAnyAtomicType, which we use as is. */
+ return makeGenericSequenceType(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t) ? t : ItemType::Ptr(BuiltinTypes::xsAnyAtomicType),
+ opt->cardinality().toWithoutMany());
+}
+
+Item SumFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));
+ Item sum(it->next());
+
+ while(sum)
+ {
+ const Item next(it->next());
+ if(!next)
+ break;
+
+ sum = ArithmeticExpression::flexiblyCalculate(sum, AtomicMathematician::Add,
+ next, m_mather, context, this,
+ ReportContext::FORG0006);
+ };
+
+ if(!sum)
+ {
+ if(m_operands.count() == 1)
+ return CommonValues::IntegerZero;
+ else
+ return m_operands.last()->evaluateSingleton(context);
+ }
+
+ return sum;
+}
+
+Expression::Ptr SumFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(AddingAggregate::typeCheck(context, reqType));
+
+ if(*CommonSequenceTypes::Empty == *m_operands.first()->staticType()->itemType())
+ {
+ if(m_operands.count() == 1)
+ return wrapLiteral(CommonValues::IntegerZero, context, this);
+ else
+ return m_operands.at(1);
+ }
+
+ if(m_operands.count() == 1)
+ return me;
+
+ const ItemType::Ptr t(m_operands.at(1)->staticType()->itemType());
+
+ if(!BuiltinTypes::numeric->xdtTypeMatches(t) &&
+ !BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t) &&
+ *CommonSequenceTypes::Empty != *t &&
+ !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t) &&
+ !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t))
+ {
+ context->error(QtXmlPatterns::tr("The second argument to %1 cannot be "
+ "of type %2. It must be of type %3, "
+ "%4, or %5.")
+ .arg(formatFunction(context->namePool(), signature()))
+ .arg(formatType(context->namePool(), m_operands.at(1)->staticType()))
+ .arg(formatType(context->namePool(), BuiltinTypes::numeric))
+ .arg(formatType(context->namePool(), BuiltinTypes::xsYearMonthDuration))
+ .arg(formatType(context->namePool(), BuiltinTypes::xsDayTimeDuration)),
+ ReportContext::FORG0006, this);
+ return me;
+ }
+
+ return me;
+}
+
+SequenceType::Ptr SumFN::staticType() const
+{
+ const SequenceType::Ptr t(m_operands.first()->staticType());
+
+ if(m_operands.count() == 1)
+ {
+ return makeGenericSequenceType(t->itemType() | BuiltinTypes::xsInteger,
+ Cardinality::exactlyOne());
+ }
+ else
+ {
+ return makeGenericSequenceType(t->itemType() | m_operands.at(1)->staticType()->itemType(),
+ t->cardinality().toWithoutMany());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qaggregatefns_p.h b/src/xmlpatterns/functions/qaggregatefns_p.h
new file mode 100644
index 0000000000..9e4eb945c7
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregatefns_p.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AggregateFNs_H
+#define Patternist_AggregateFNs_H
+
+#include "qaggregator_p.h"
+#include "qatomiccomparator_p.h"
+#include "qatomicmathematician_p.h"
+#include "qcomparisonplatform_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#aggregate-functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 15.4 Aggregate Functions</a>.
+ *
+ * @todo document that some functions have both eval funcs implented.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:count()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CountFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * If @p reqType is CommonSequenceTypes::EBV, this function call is rewritten
+ * into a call to <tt>fn:exists()</tt>. Hence, <tt>if(count(X)) then ...</tt> is
+ * rewritten into <tt>if(exists(X)) then ...</tt>.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ /**
+ * If CountFN's operand has a Cardinality that is exact, as per Cardinality::isExact(),
+ * it is rewritten to the Cardinality's count.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ };
+
+ /**
+ * @short Base class for the implementations of the <tt>fn:avg()</tt> and <tt>fn:sum()</tt> function.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class AddingAggregate : public FunctionCall
+ {
+ public:
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ protected:
+ AtomicMathematician::Ptr m_mather;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:avg()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class AvgFN : public AddingAggregate
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::Ptr staticType() const;
+ private:
+ AtomicMathematician::Ptr m_adder;
+ AtomicMathematician::Ptr m_divider;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:sum()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class SumFN : public AddingAggregate
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qaggregator.cpp b/src/xmlpatterns/functions/qaggregator.cpp
new file mode 100644
index 0000000000..b585e77091
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregator.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qaggregator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SequenceType::Ptr Aggregator::staticType() const
+{
+ const SequenceType::Ptr t(m_operands.first()->staticType());
+ ItemType::Ptr itemType(t->itemType());
+
+ /* Since we have types that are derived from xs:integer, this ensures that
+ * the static type is xs:integer even if the argument is for
+ * instance xs:unsignedShort. */
+ if(BuiltinTypes::xsInteger->xdtTypeMatches(itemType) &&
+ !itemType->xdtTypeMatches(BuiltinTypes::xsInteger))
+ {
+ itemType = BuiltinTypes::xsInteger;
+ }
+
+ return makeGenericSequenceType(itemType,
+ t->cardinality().toWithoutMany());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qaggregator_p.h b/src/xmlpatterns/functions/qaggregator_p.h
new file mode 100644
index 0000000000..7b7e90b4c2
--- /dev/null
+++ b/src/xmlpatterns/functions/qaggregator_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Aggregator_H
+#define Patternist_Aggregator_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Carries a staticType() implementation appropriate
+ * for functions which returns a singleton value derived from its first argument.
+ *
+ * One example of such a function is FloorFN, implementing <tt>fn:floor()</tt>,
+ * which returns a single value of the same type as the first argument, or the empty
+ * sequence if the first argument evaluates to the empty sequence.
+ *
+ * Aggregator is abstract, and exists for saving code. It is inherited
+ * by classes which needs the staticType() implementation this class provides.
+ *
+ * @see Piper
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class Aggregator : public FunctionCall
+ {
+ public:
+ /**
+ * @returns a static type where the ItemType is the same as this FunctionCall's first
+ * argument, and the Cardinality is as return from Cardinality::toWithoutMany().
+ */
+ virtual SequenceType::Ptr staticType() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qassemblestringfns.cpp b/src/xmlpatterns/functions/qassemblestringfns.cpp
new file mode 100644
index 0000000000..513ba6788c
--- /dev/null
+++ b/src/xmlpatterns/functions/qassemblestringfns.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonvalues_p.h"
+#include "qpatternistlocale_p.h"
+#include "qschemanumeric_p.h"
+#include "qatomicstring_p.h"
+#include "qtocodepointsiterator_p.h"
+
+#include "qassemblestringfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/*
+ * Determines whether @p cp is a valid XML 1.0 character.
+ *
+ * @see <a href="http://www.w3.org/TR/REC-xml/#charsets">Extensible Markup
+ * Language (XML) 1.0 (Third Edition)2.2 Characters</a>
+ */
+static inline bool isValidXML10Char(const qint32 cp)
+{
+ /* [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] |
+ * [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+ */
+ return (cp == 0x9 ||
+ cp == 0xA ||
+ cp == 0xD ||
+ (0x20 <= cp && cp <= 0xD7FF) ||
+ (0xE000 <= cp && cp <= 0xFFFD) ||
+ (0x10000 <= cp && cp <= 0x10FFFF));
+}
+
+Item CodepointsToStringFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));
+
+ if(!it)
+ return CommonValues::EmptyString;
+
+ QString retval;
+ Item item(it->next());
+ while(item)
+ {
+ const qint32 cp = static_cast<qint32>(item.as<Numeric>()->toInteger());
+
+ if(!isValidXML10Char(cp))
+ {
+ context->error(QtXmlPatterns::tr("%1 is not a valid XML 1.0 character.")
+ .arg(formatData(QLatin1String("0x") +
+ QString::number(cp, 16))),
+ ReportContext::FOCH0001, this);
+
+ return CommonValues::EmptyString;
+ }
+ retval.append(QChar(cp));
+ item = it->next();
+ }
+
+ return AtomicString::fromValue(retval);
+}
+
+Item::Iterator::Ptr StringToCodepointsFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+ if(!item)
+ return CommonValues::emptyIterator;
+
+ const QString str(item.stringValue());
+ if(str.isEmpty())
+ return CommonValues::emptyIterator;
+ else
+ return Item::Iterator::Ptr(new ToCodepointsIterator(str));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qassemblestringfns_p.h b/src/xmlpatterns/functions/qassemblestringfns_p.h
new file mode 100644
index 0000000000..832e28315c
--- /dev/null
+++ b/src/xmlpatterns/functions/qassemblestringfns_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AssembleStringFNs_H
+#define Patternist_AssembleStringFNs_H
+
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#func-assemble-disassemble-string">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 7.2 Functions to Assemble and Disassemble Strings</a>.
+ * <a href="http://www.azillionmonkeys.com/qed/unicode.html">Quick Guide to understanding
+ * Unicode Data Transfer Formats</a>
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:codepoints-to-string()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CodepointsToStringFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:string-to-codepoints()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class StringToCodepointsFN : public FunctionCall
+ {
+ public:
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qbooleanfns.cpp b/src/xmlpatterns/functions/qbooleanfns.cpp
new file mode 100644
index 0000000000..c20b0e35f7
--- /dev/null
+++ b/src/xmlpatterns/functions/qbooleanfns.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qoptimizationpasses_p.h"
+
+#include "qbooleanfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool TrueFN::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return true;
+}
+
+bool FalseFN::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return false;
+}
+
+bool NotFN::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ /* That little '!' is quite important in this function -- I forgot it ;-) */
+ return !m_operands.first()->evaluateEBV(context);
+}
+
+OptimizationPass::List NotFN::optimizationPasses() const
+{
+ return OptimizationPasses::notFN;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qbooleanfns_p.h b/src/xmlpatterns/functions/qbooleanfns_p.h
new file mode 100644
index 0000000000..989098194f
--- /dev/null
+++ b/src/xmlpatterns/functions/qbooleanfns_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_BooleanFNs_H
+#define Patternist_BooleanFNs_H
+
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#boolean-functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 9 Functions and Operators on Boolean Values</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:true()</tt>.
+ *
+ * The implementation always rewrites itself to a boolean value at compile time.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class TrueFN : public FunctionCall
+ {
+ public:
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:false()</tt>.
+ *
+ * The implementation always rewrites itself to a boolean value at compile time.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class FalseFN : public FunctionCall
+ {
+ public:
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:not()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NotFN : public FunctionCall
+ {
+ public:
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qcomparescaseaware.cpp b/src/xmlpatterns/functions/qcomparescaseaware.cpp
new file mode 100644
index 0000000000..2fee0f705f
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparescaseaware.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvaluecomparison_p.h"
+
+#include "qcomparescaseaware_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ComparesCaseAware::ComparesCaseAware() : m_caseSensitivity(Qt::CaseSensitive)
+{
+}
+
+Expression::Ptr ComparesCaseAware::compress(const StaticContext::Ptr &context)
+{
+ Q_ASSERT(m_operands.size() >= 2);
+
+ if(ValueComparison::isCaseInsensitiveCompare(m_operands.first(), m_operands[1]))
+ m_caseSensitivity = Qt::CaseInsensitive;
+ else
+ {
+ /* Yes, we could probably skip this since m_caseSensitivity is initialized to this value,
+ * but perhaps subsequent calls to compress() can make isCaseInsensitiveCompare() return
+ * a different value. */
+ m_caseSensitivity = Qt::CaseSensitive;
+ }
+
+ return FunctionCall::compress(context);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qcomparescaseaware_p.h b/src/xmlpatterns/functions/qcomparescaseaware_p.h
new file mode 100644
index 0000000000..7791949d25
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparescaseaware_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ComparesCaseAware_H
+#define Patternist_ComparesCaseAware_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base-class for functions that compares strings and provides
+ * an opportunity to optimize compares intended to be case insensitive.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ComparesCaseAware : public FunctionCall
+ {
+ public:
+ /**
+ * Performs initialization.
+ */
+ ComparesCaseAware();
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * Tells whether the return value of the two operands must be compared
+ * case insensitively or not.
+ */
+ inline Qt::CaseSensitivity caseSensitivity() const
+ {
+ return m_caseSensitivity;
+ }
+
+ private:
+ Qt::CaseSensitivity m_caseSensitivity;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qcomparestringfns.cpp b/src/xmlpatterns/functions/qcomparestringfns.cpp
new file mode 100644
index 0000000000..1f2fcee695
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparestringfns.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonnamespaces_p.h"
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qinteger_p.h"
+#include "qatomicstring_p.h"
+
+#include "qcomparestringfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item CodepointEqualFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operands.first()->evaluateSingleton(context));
+ if(!op1)
+ return Item();
+
+ const Item op2(m_operands.last()->evaluateSingleton(context));
+ if(!op2)
+ return Item();
+
+ if(caseSensitivity() == Qt::CaseSensitive)
+ return Boolean::fromValue(op1.stringValue() == op2.stringValue());
+ else
+ {
+ const QString s1(op1.stringValue());
+ const QString s2(op2.stringValue());
+
+ return Boolean::fromValue(s1.length() == s2.length() &&
+ s1.startsWith(s2, Qt::CaseInsensitive));
+ }
+}
+
+Item CompareFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operands.first()->evaluateSingleton(context));
+ if(!op1)
+ return Item();
+
+ const Item op2(m_operands.at(1)->evaluateSingleton(context));
+ if(!op2)
+ return Item();
+
+ const int retval = caseSensitivity() == Qt::CaseSensitive
+ ? op1.stringValue().compare(op2.stringValue())
+ : op1.stringValue().toLower().compare(op2.stringValue().toLower());
+
+ if(retval > 0)
+ return CommonValues::IntegerOne;
+ else if(retval < 0)
+ return CommonValues::IntegerOneNegative;
+ else
+ {
+ Q_ASSERT(retval == 0);
+ return CommonValues::IntegerZero;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qcomparestringfns_p.h b/src/xmlpatterns/functions/qcomparestringfns_p.h
new file mode 100644
index 0000000000..11ebd2a456
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparestringfns_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CompareStringFNs_H
+#define Patternist_CompareStringFNs_H
+
+#include "qcomparescaseaware_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#string-compare">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 7.3 Equality and Comparison of Strings</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:codepoint-equal()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CodepointEqualFN : public ComparesCaseAware
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:compare()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CompareFN : public ComparesCaseAware
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qcomparingaggregator.cpp b/src/xmlpatterns/functions/qcomparingaggregator.cpp
new file mode 100644
index 0000000000..a87e659b48
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparingaggregator.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file qcomparingaggregator.cpp
+ * @short This file is included by qcomparingaggregator_p.h.
+ * If you need includes in this file, put them in qcomparingaggregator_p.h, outside of the namespace.
+ */
+
+template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result>
+inline Item
+ComparingAggregator<oper, result>::applyNumericPromotion(const Item &old,
+ const Item &nev,
+ const Item &newVal) const
+{
+ Q_ASSERT(old);
+ Q_ASSERT(nev);
+ Q_ASSERT(newVal);
+ const ItemType::Ptr to(old.type());
+ const ItemType::Ptr tn(nev.type());
+
+ if(!(BuiltinTypes::numeric->xdtTypeMatches(to) && BuiltinTypes::numeric->xdtTypeMatches(tn)))
+ return newVal; /* At least one of them isn't numeric. */
+ else if(BuiltinTypes::xsDouble->xdtTypeMatches(to) || BuiltinTypes::xsDouble->xdtTypeMatches(tn))
+ return toItem(Double::fromValue(newVal.as<Numeric>()->toDouble()));
+ else if(BuiltinTypes::xsFloat->xdtTypeMatches(to) || BuiltinTypes::xsFloat->xdtTypeMatches(tn))
+ return toItem(Float::fromValue(newVal.as<Numeric>()->toDouble()));
+ else if(BuiltinTypes::xsInteger->xdtTypeMatches(to) &&
+ BuiltinTypes::xsInteger->xdtTypeMatches(tn))
+ return newVal; /* Both must be xs:integer. */
+ else
+ return toItem(Decimal::fromValue(newVal.as<Numeric>()->toDecimal()));
+}
+
+template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result>
+Item
+ComparingAggregator<oper, result>::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));
+ Item largest;
+
+ while(true)
+ {
+ Item next(it->next());
+
+ if(!next)
+ {
+ return largest;
+ }
+
+ AtomicComparator::Ptr comp(comparator());
+
+ if(!comp)
+ {
+ ItemType::Ptr t1(next.type());
+ Q_ASSERT(t1);
+
+ if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1))
+ {
+ next = cast(next, context);
+ t1 = BuiltinTypes::xsDouble;
+ }
+
+ if(!largest)
+ {
+ largest = next;
+ continue;
+ }
+
+ Q_ASSERT(largest);
+ comp = fetchComparator(largest.type(), t1, context);
+ Q_ASSERT(comp);
+ }
+ else if(!largest)
+ {
+ largest = next;
+ continue;
+ }
+
+ if(comp->compare(next, operatorID(), largest) == result)
+ {
+ largest = applyNumericPromotion(largest, next, next);
+ continue;
+ }
+
+ const ItemType::Ptr t(next.type());
+
+ if(BuiltinTypes::xsDouble->xdtTypeMatches(t) &&
+ next.as<Numeric>()->isNaN())
+ {
+ return CommonValues::DoubleNaN;
+ }
+ else if(BuiltinTypes::xsFloat->xdtTypeMatches(t) &&
+ next.as<Numeric>()->isNaN())
+ {
+ if(BuiltinTypes::xsDouble->xdtTypeMatches(largest.type()))
+ return CommonValues::DoubleNaN;
+
+ /* If we have a xs:double somewhere, we must promote the NaN value to xs:double,
+ * and we really should raise error on invalid value. */
+ largest = it->next();
+
+ while(largest)
+ {
+ const ItemType::Ptr tf(largest.type());
+ if(BuiltinTypes::xsDouble->xdtTypeMatches(tf))
+ return CommonValues::DoubleNaN;
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(tf))
+ {
+ /* Attempt a convert, which will raise an error if it doesn't work out. */
+ cast(largest, context);
+ return CommonValues::DoubleNaN;
+ }
+ else if(!BuiltinTypes::numeric->xdtTypeMatches(tf))
+ {
+ fetchComparator(BuiltinTypes::xsFloat, tf, context);
+ }
+ else
+ largest = it->next();
+ };
+
+ return CommonValues::FloatNaN;
+ }
+ else
+ largest = applyNumericPromotion(largest, next, largest);
+ }
+}
+
+template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result>
+Expression::Ptr
+ComparingAggregator<oper, result>::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(oper == AtomicComparator::OperatorGreaterThan ||
+ oper == AtomicComparator::OperatorLessThan);
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+
+ ItemType::Ptr t1(m_operands.first()->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1)
+ return EmptySequence::create(this, context);
+ else if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ BuiltinTypes::numeric->xdtTypeMatches(t1))
+ return me;
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1))
+ {
+ m_operands.replace(0, Expression::Ptr(new UntypedAtomicConverter(m_operands.first(),
+ BuiltinTypes::xsDouble)));
+ t1 = m_operands.first()->staticType()->itemType();
+ }
+ else if(!BuiltinTypes::xsString->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsAnyURI->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsDate->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsTime->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsDateTime->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1))
+ {
+ context->error(QtXmlPatterns::tr("The first argument to %1 cannot be of type %2.")
+ .arg(formatFunction(context->namePool(), signature()))
+ .arg(formatType(context->namePool(), m_operands.first()->staticType())),
+ ReportContext::FORG0006, this);
+ return me;
+ }
+
+ if(!m_operands.first()->staticType()->cardinality().allowsMany())
+ return m_operands.first();
+
+ prepareComparison(fetchComparator(t1, t1, context));
+
+ return me;
+}
+
diff --git a/src/xmlpatterns/functions/qcomparingaggregator_p.h b/src/xmlpatterns/functions/qcomparingaggregator_p.h
new file mode 100644
index 0000000000..374fa7a8c2
--- /dev/null
+++ b/src/xmlpatterns/functions/qcomparingaggregator_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ComparingAggregator_H
+#define Patternist_ComparingAggregator_H
+
+/**
+ * @file qcomparingaggregator_p.h
+ * @short Contains the implementations for the functions <tt>fn:max()</tt>, MaxFN,
+ * and <tt>fn:min()</tt>, MinFN, and the class ComparingAggregator.
+ */
+
+#include "qabstractfloat_p.h"
+#include "qdecimal_p.h"
+#include "qcastingplatform_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qliteral_p.h"
+#include "qaggregator_p.h"
+#include "quntypedatomicconverter_p.h"
+#include "qpatternistlocale_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for the implementations of the <tt>fn:min()</tt> and <tt>fn:max()</tt> function.
+ *
+ * What function that more specifically is
+ * followed, depends on how the constructor is called.
+ *
+ * @see MaxFN
+ * @see MinFN
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ template <AtomicComparator::Operator oper, AtomicComparator::ComparisonResult result>
+ class ComparingAggregator : public Aggregator,
+ public ComparisonPlatform<ComparingAggregator<oper, result>,
+ true, AtomicComparator::AsValueComparison,
+ ReportContext::FORG0006>,
+ public CastingPlatform<ComparingAggregator<oper, result>, true>
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return oper;
+ }
+
+ inline ItemType::Ptr targetType() const
+ {
+ return BuiltinTypes::xsDouble;
+ }
+
+ private:
+ inline Item applyNumericPromotion(const Item &old,
+ const Item &nev,
+ const Item &newVal) const;
+
+ using ComparisonPlatform<ComparingAggregator<oper, result>,
+ true,
+ AtomicComparator::AsValueComparison,
+ ReportContext::FORG0006>::comparator;
+ using ComparisonPlatform<ComparingAggregator<oper, result>,
+ true,
+ AtomicComparator::AsValueComparison,
+ ReportContext::FORG0006>::fetchComparator;
+ using CastingPlatform<ComparingAggregator<oper, result>, true>::cast;
+ };
+
+#include "qcomparingaggregator.cpp"
+
+ /**
+ * @short An instantiation of ComparingAggregator suitable for <tt>fn:max()</tt>.
+ *
+ * @ingroup Patternist_functions
+ */
+ typedef ComparingAggregator<AtomicComparator::OperatorGreaterThan, AtomicComparator::GreaterThan> MaxFN;
+
+ /**
+ * @short An instantiation of ComparingAggregator suitable for <tt>fn:max()</tt>.
+ *
+ * @ingroup Patternist_functions
+ */
+ typedef ComparingAggregator<AtomicComparator::OperatorLessThan, AtomicComparator::LessThan> MinFN;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp b/src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp
new file mode 100644
index 0000000000..529cab968f
--- /dev/null
+++ b/src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcastas_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qfunctionargument_p.h"
+#include "qfunctioncall_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qschematype_p.h"
+#include "qschematypefactory_p.h"
+
+#include "qconstructorfunctionsfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ConstructorFunctionsFactory::ConstructorFunctionsFactory(const NamePool::Ptr &np, const SchemaTypeFactory::Ptr &f) : m_typeFactory(f)
+{
+ Q_ASSERT(m_typeFactory);
+ Q_ASSERT(np);
+ SchemaType::Hash::const_iterator it(m_typeFactory->types().constBegin());
+ const SchemaType::Hash::const_iterator end(m_typeFactory->types().constEnd());
+
+ FunctionArgument::List args;
+ const QXmlName argName(StandardNamespaces::empty, StandardLocalNames::sourceValue);
+
+ args.append(FunctionArgument::Ptr(new FunctionArgument(argName,
+ CommonSequenceTypes::ZeroOrOneAtomicType)));
+
+ while(it != end)
+ {
+ if(!BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(*it) ||
+ *BuiltinTypes::xsAnyAtomicType == *static_cast<const AtomicType *>((*it).data()) ||
+ *BuiltinTypes::xsNOTATION == *static_cast<const AtomicType *>((*it).data()))
+ {
+ /* It's not a valid type for a constructor function -- skip it. */
+ ++it;
+ continue;
+ }
+
+ const QXmlName name((*it)->name(np));
+ FunctionSignature::Ptr s(new FunctionSignature(name, 1, 1,
+ makeGenericSequenceType(AtomicType::Ptr(*it),
+ Cardinality::zeroOrOne())));
+ s->setArguments(args);
+ m_signatures.insert(name, s);
+ ++it;
+ }
+}
+
+Expression::Ptr ConstructorFunctionsFactory::retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const
+{
+ Q_UNUSED(sign);
+
+ /* This function is only called if the callsite is valid, so createSchemaType() will always
+ * return an AtomicType. */
+ const AtomicType::Ptr at(static_cast<AtomicType *>(m_typeFactory->createSchemaType(name).data()));
+
+ return Expression::Ptr(new CastAs(args.first(),
+ makeGenericSequenceType(at,
+ Cardinality::zeroOrOne())));
+}
+
+FunctionSignature::Ptr ConstructorFunctionsFactory::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name)
+{
+ Q_UNUSED(np);
+ return functionSignatures().value(name);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h b/src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h
new file mode 100644
index 0000000000..9861f7c5b1
--- /dev/null
+++ b/src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ConstructorFunctionsFactory_H
+#define Patternist_ConstructorFunctionsFactory_H
+
+#include "qabstractfunctionfactory_p.h"
+#include "qschematypefactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short A function factory that handles the builtin constructor functions, such
+ * as <tt>xs:time()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-constructor-functions">XML Path
+ * Language (XPath) 2.0, 3.10.4 Constructor Functions</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class ConstructorFunctionsFactory : public AbstractFunctionFactory
+ {
+ public:
+ ConstructorFunctionsFactory(const NamePool::Ptr &np, const SchemaTypeFactory::Ptr &);
+
+ virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name);
+
+ protected:
+ virtual Expression::Ptr retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const;
+
+ private:
+ const SchemaTypeFactory::Ptr m_typeFactory;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qcontextfns.cpp b/src/xmlpatterns/functions/qcontextfns.cpp
new file mode 100644
index 0000000000..89da9db23c
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextfns.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qdate_p.h"
+#include "qschemadatetime_p.h"
+#include "qdaytimeduration_p.h"
+#include "qinteger_p.h"
+#include "qliteral_p.h"
+#include "qatomicstring_p.h"
+#include "qschematime_p.h"
+
+#include "qcontextfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item PositionFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ return Integer::fromValue(context->contextPosition());
+}
+
+Item LastFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ return Integer::fromValue(context->contextSize());
+}
+
+Item ImplicitTimezoneFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return toItem(context->implicitTimezone());
+}
+
+Item CurrentDateTimeFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return toItem(DateTime::fromDateTime(context->currentDateTime()));
+}
+
+Item CurrentDateFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return toItem(Date::fromDateTime(context->currentDateTime()));
+}
+
+Item CurrentTimeFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return toItem(SchemaTime::fromDateTime(context->currentDateTime()));
+}
+
+Expression::Ptr StaticBaseURIFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* Our base URI can never be undefined. */
+ return wrapLiteral(toItem(AnyURI::fromValue(context->baseURI())), context, this)->typeCheck(context, reqType);
+}
+
+Expression::Ptr DefaultCollationFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ return wrapLiteral(AtomicString::fromValue(context->defaultCollation().toString()), context, this)->typeCheck(context, reqType);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qcontextfns_p.h b/src/xmlpatterns/functions/qcontextfns_p.h
new file mode 100644
index 0000000000..08698e7423
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextfns_p.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ContextFNs_H
+#define Patternist_ContextFNs_H
+
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#context">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 16 Context Functions</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:position()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-position">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.1 fn:position</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class PositionFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:last()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-last">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.2 fn:last</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class LastFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:implicit-timezone()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-implicit-timezone">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.6 fn:implicit-timezone</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ImplicitTimezoneFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:current-dateTime()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-current-dateTime">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.3 fn:current-dateTime</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CurrentDateTimeFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:current-date()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-current-date">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.4 fn:current-date</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CurrentDateFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:current-time()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-current-time">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.5 fn:current-date</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CurrentTimeFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:default-collation()</tt>.
+ *
+ * This is done by rewriting to StaticContext::defaultCollation() at the typeCheck() stage.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-default-collation">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.7 fn:default-collation</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DefaultCollationFN : public FunctionCall
+ {
+ public:
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ };
+
+ /**
+ * @short Implements the function <tt>fn:static-base-uri()</tt>.
+ *
+ * This is done by rewriting to StaticContext::baseURI() at the typeCheck() stage.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-static-base-uri">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 16.8 fn:static-base-uri</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class StaticBaseURIFN : public FunctionCall
+ {
+ public:
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qcontextnodechecker.cpp b/src/xmlpatterns/functions/qcontextnodechecker.cpp
new file mode 100644
index 0000000000..2d1df49519
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextnodechecker.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcontextnodechecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void ContextNodeChecker::checkTargetNode(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context,
+ const ReportContext::ErrorCode code) const
+{
+ if(node.root().kind() != QXmlNodeModelIndex::Document)
+ {
+ context->error(QtXmlPatterns::tr("The root node of the second argument "
+ "to function %1 must be a document "
+ "node. %2 is not a document node.")
+ .arg(formatFunction(context->namePool(), signature()),
+ formatData(node)),
+ code, this);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qcontextnodechecker_p.h b/src/xmlpatterns/functions/qcontextnodechecker_p.h
new file mode 100644
index 0000000000..5745bc45a5
--- /dev/null
+++ b/src/xmlpatterns/functions/qcontextnodechecker_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ContextNodeChecker_H
+#define Patternist_ContextNodeChecker_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Helper class that checks that the context node is a document
+ * node.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ContextNodeChecker : public FunctionCall
+ {
+ protected:
+ /**
+ * @short Checks that the root node of @p node is a document node, and
+ * otherwise issues an error.
+ */
+ void checkTargetNode(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context,
+ const ReportContext::ErrorCode) const;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qcurrentfn.cpp b/src/xmlpatterns/functions/qcurrentfn.cpp
new file mode 100644
index 0000000000..f4ae778231
--- /dev/null
+++ b/src/xmlpatterns/functions/qcurrentfn.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcurrentfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item CurrentFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->currentItem();
+}
+
+Expression::Ptr CurrentFN::compress(const StaticContext::Ptr &context)
+{
+ m_itemType = context->currentItemType();
+ return FunctionCall::compress(context);
+}
+
+Expression::Ptr CurrentFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_itemType = context->currentItemType();
+ return FunctionCall::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr CurrentFN::staticType() const
+{
+ if(m_itemType)
+ return makeGenericSequenceType(m_itemType, Cardinality::exactlyOne());
+ else
+ return CommonSequenceTypes::ExactlyOneItem;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qcurrentfn_p.h b/src/xmlpatterns/functions/qcurrentfn_p.h
new file mode 100644
index 0000000000..cc9d2950d5
--- /dev/null
+++ b/src/xmlpatterns/functions/qcurrentfn_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CurrentFN_H
+#define Patternist_CurrentFN_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XSL-T's function <tt>fn:current()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @since 4.5
+ */
+ class CurrentFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+
+ private:
+ ItemType::Ptr m_itemType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qdatetimefn.cpp b/src/xmlpatterns/functions/qdatetimefn.cpp
new file mode 100644
index 0000000000..5727794c43
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefn.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomiccomparator_p.h"
+#include "qcommonvalues_p.h"
+#include "qschemadatetime_p.h"
+#include "qdaytimeduration_p.h"
+#include "qdecimal_p.h"
+#include "qinteger_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qdatetimefn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item DateTimeFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item di(m_operands.first()->evaluateSingleton(context));
+ if(!di)
+ return Item();
+
+ const Item ti(m_operands.last()->evaluateSingleton(context));
+ if(!ti)
+ return Item();
+
+ QDateTime date(di.as<AbstractDateTime>()->toDateTime());
+ Q_ASSERT(date.isValid());
+ QDateTime time(ti.as<AbstractDateTime>()->toDateTime());
+ Q_ASSERT(time.isValid());
+
+ if(date.timeSpec() == time.timeSpec() || /* Identical timezone properties. */
+ time.timeSpec() == Qt::LocalTime) /* time has no timezone, but date do. */
+ {
+ date.setTime(time.time());
+ Q_ASSERT(date.isValid());
+ return DateTime::fromDateTime(date);
+ }
+ else if(date.timeSpec() == Qt::LocalTime) /* date has no timezone, but time do. */
+ {
+ time.setDate(date.date());
+ Q_ASSERT(time.isValid());
+ return DateTime::fromDateTime(time);
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("If both values have zone offsets, "
+ "they must have the same zone offset. "
+ "%1 and %2 are not the same.")
+ .arg(formatData(di.stringValue()),
+ formatData(di.stringValue())),
+ ReportContext::FORG0008, this);
+ return Item(); /* Silence GCC warning. */
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qdatetimefn_p.h b/src/xmlpatterns/functions/qdatetimefn_p.h
new file mode 100644
index 0000000000..69567d25f0
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_DateTimeFN_H
+#define Patternist_DateTimeFN_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:dateTime()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-dateTime">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 5.2 A Special Constructor Function for xs:dateTime</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DateTimeFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qdatetimefns.cpp b/src/xmlpatterns/functions/qdatetimefns.cpp
new file mode 100644
index 0000000000..756504bff6
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefns.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qdatetimefns_p.h.
+ * If you need includes in this file, put them in qdatetimefns_p.h, outside of the namespace.
+ */
+
+template<typename TSubClass>
+Item ExtractFromDurationFN<TSubClass>::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+ if(item)
+ {
+ return static_cast<const TSubClass *>(this)->
+ extract(item.as<AbstractDuration>());
+ }
+ else
+ return Item();
+}
+
+Item YearsFromDurationFN::extract(const AbstractDuration *const duration) const
+{
+ return Integer::fromValue(duration->years() * (duration->isPositive() ? 1 : -1));
+}
+
+Item MonthsFromDurationFN::extract(const AbstractDuration *const duration) const
+{
+ return Integer::fromValue(duration->months() * (duration->isPositive() ? 1 : -1));
+}
+
+Item DaysFromDurationFN::extract(const AbstractDuration *const duration) const
+{
+ return Integer::fromValue(duration->days() * (duration->isPositive() ? 1 : -1));
+}
+
+Item HoursFromDurationFN::extract(const AbstractDuration *const duration) const
+{
+ return Integer::fromValue(duration->hours() * (duration->isPositive() ? 1 : -1));
+}
+
+Item MinutesFromDurationFN::extract(const AbstractDuration *const duration) const
+{
+ return Integer::fromValue(duration->minutes() * (duration->isPositive() ? 1 : -1));
+}
+
+Item SecondsFromDurationFN::extract(const AbstractDuration *const duration) const
+{
+ return toItem(Decimal::fromValue((duration->seconds() + duration->mseconds() / 1000.0) *
+ (duration->isPositive() ? 1 : -1)));
+}
+
+template<typename TSubClass>
+Item ExtractFromDateTimeFN<TSubClass>::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+ if(item)
+ {
+ return static_cast<const TSubClass *>(this)->
+ extract(item.as<AbstractDateTime>()->toDateTime());
+ }
+ else
+ return Item();
+}
+
+Item YearFromAbstractDateTimeFN::extract(const QDateTime &dt) const
+{
+ return Integer::fromValue(dt.date().year());
+}
+
+Item DayFromAbstractDateTimeFN::extract(const QDateTime &dt) const
+{
+ return Integer::fromValue(dt.date().day());
+}
+
+Item MinutesFromAbstractDateTimeFN::extract(const QDateTime &dt) const
+{
+ return Integer::fromValue(dt.time().minute());
+}
+
+Item SecondsFromAbstractDateTimeFN::extract(const QDateTime &dt) const
+{
+ const QTime time(dt.time());
+ return toItem(Decimal::fromValue(time.second() + time.msec() / 1000.0));
+}
+
+Item TimezoneFromAbstractDateTimeFN::extract(const QDateTime &dt) const
+{
+ if(dt.timeSpec() == Qt::UTC)
+ return toItem(CommonValues::DayTimeDurationZero);
+ else if(dt.timeSpec() == Qt::OffsetFromUTC)
+ return toItem(DayTimeDuration::fromSeconds(dt.utcOffset()));
+ else
+ return Item();
+}
+
+Item MonthFromAbstractDateTimeFN::extract(const QDateTime &dt) const
+{
+ return Integer::fromValue(dt.date().month());
+}
+
+Item HoursFromAbstractDateTimeFN::extract(const QDateTime &dt) const
+{
+ return Integer::fromValue(dt.time().hour());
+}
+
diff --git a/src/xmlpatterns/functions/qdatetimefns_p.h b/src/xmlpatterns/functions/qdatetimefns_p.h
new file mode 100644
index 0000000000..0adb3f3ef7
--- /dev/null
+++ b/src/xmlpatterns/functions/qdatetimefns_p.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_DateTimeFNs_H
+#define Patternist_DateTimeFNs_H
+
+#include "qatomiccomparator_p.h"
+#include "qcommonvalues_p.h"
+#include "qschemadatetime_p.h"
+#include "qdaytimeduration_p.h"
+#include "qdecimal_p.h"
+#include "qinteger_p.h"
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#component-exraction-functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 10.5 Component Extraction Functions on Durations, Dates and Times</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Helper class for implementing functions extracting components from durations.
+ *
+ * Each sub-class must implement this function:
+ *
+ * @code
+ * Item extract(const AbstractDuration *const duration) const;
+ * @endcode
+ *
+ * This function performs the actual component extraction from the argument, that
+ * is guaranteed to never be @c null.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ template<typename TSubClass>
+ class ExtractFromDurationFN : public FunctionCall
+ {
+ public:
+ /**
+ * Takes care of the argument handling, and, if applicable,
+ * calls extract() with the value of the operand.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:years-from-duration()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class YearsFromDurationFN : public ExtractFromDurationFN<YearsFromDurationFN>
+ {
+ public:
+ inline Item extract(const AbstractDuration *const duration) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:months-from-duration()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class MonthsFromDurationFN : public ExtractFromDurationFN<MonthsFromDurationFN>
+ {
+ public:
+ inline Item extract(const AbstractDuration *const duration) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:days-from-duration()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DaysFromDurationFN : public ExtractFromDurationFN<DaysFromDurationFN>
+ {
+ public:
+ inline Item extract(const AbstractDuration *const duration) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:hours-from-duration()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class HoursFromDurationFN : public ExtractFromDurationFN<HoursFromDurationFN>
+ {
+ public:
+ inline Item extract(const AbstractDuration *const duration) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:minutes-from-duration()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class MinutesFromDurationFN : public ExtractFromDurationFN<MinutesFromDurationFN>
+ {
+ public:
+ inline Item extract(const AbstractDuration *const duration) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:seconds-from-duration()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class SecondsFromDurationFN : public ExtractFromDurationFN<SecondsFromDurationFN>
+ {
+ public:
+ inline Item extract(const AbstractDuration *const duration) const;
+ };
+
+ /**
+ * @short Helper class for implementing functions extracting components
+ * from date/time values.
+ *
+ * Each sub-class must implement this function:
+ *
+ * @code
+ * Item extract(const AbstractDuration *const duration) const;
+ * @endcode
+ *
+ * This function performs the actual component extraction from the argument, that
+ * is guaranteed to never be @c null.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ template<typename TSubClass>
+ class ExtractFromDateTimeFN : public FunctionCall
+ {
+ public:
+ /**
+ * Takes care of the argument handling, and, if applicable,
+ * calls extract() with the value of the operand.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Extracts the year property from a sub-class of AbstractDateTime such as DateTime or Date.
+ * This function implements <tt>fn:year-from-dateTime()</tt> and <tt>fn:year-from-date()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class YearFromAbstractDateTimeFN : public ExtractFromDateTimeFN<YearFromAbstractDateTimeFN>
+ {
+ public:
+ inline Item extract(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short Extracts the day property from a sub-class of AbstractDateTime such as DateTime or Date.
+ * This function implements <tt>fn:day-from-dateTime()</tt> and <tt>fn:day-from-date()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DayFromAbstractDateTimeFN : public ExtractFromDateTimeFN<DayFromAbstractDateTimeFN>
+ {
+ public:
+ inline Item extract(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short Extracts the minute property from a sub-class of AbstractDateTime such as DateTime or SchemaTime.
+ * Implements the functions <tt>fn:hours-from-dateTime()</tt> and
+ * <tt>fn:hours-from-time()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class HoursFromAbstractDateTimeFN : public ExtractFromDateTimeFN<HoursFromAbstractDateTimeFN>
+ {
+ public:
+ inline Item extract(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short Extracts the minutes property from a sub-class of AbstractDateTime such as DateTime or Date.
+ * Implements the functions <tt>fn:minutes-from-dateTime()</tt> and
+ * <tt>fn:minutes-from-time()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class MinutesFromAbstractDateTimeFN : public ExtractFromDateTimeFN<MinutesFromAbstractDateTimeFN>
+ {
+ public:
+ inline Item extract(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short Extracts the seconds property from a sub-class of AbstractDateTime such as DateTime or Date.
+ * Implements the functions <tt>fn:seconds-from-dateTime()</tt> and
+ * <tt>fn:seconds-from-time()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class SecondsFromAbstractDateTimeFN : public ExtractFromDateTimeFN<SecondsFromAbstractDateTimeFN>
+ {
+ public:
+ inline Item extract(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short Extracts the timezone property from a sub-class of AbstractDateTime such as DateTime or Date.
+ * Implements the functions <tt>fn:timezone-from-dateTime()</tt>,
+ * <tt>fn:timezone-from-time()</tt> and <tt>fn:timezone-from-date()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class TimezoneFromAbstractDateTimeFN : public ExtractFromDateTimeFN<TimezoneFromAbstractDateTimeFN>
+ {
+ public:
+ inline Item extract(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short implements the functions <tt>fn:month-from-dateTime()</tt> and <tt>fn:month-from-date()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class MonthFromAbstractDateTimeFN : public ExtractFromDateTimeFN<MonthFromAbstractDateTimeFN>
+ {
+ public:
+ inline Item extract(const QDateTime &dt) const;
+ };
+
+#include "qdatetimefns.cpp"
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qdeepequalfn.cpp b/src/xmlpatterns/functions/qdeepequalfn.cpp
new file mode 100644
index 0000000000..133ab60f44
--- /dev/null
+++ b/src/xmlpatterns/functions/qdeepequalfn.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+#include "qschemanumeric_p.h"
+
+#include "qdeepequalfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool DeepEqualFN::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it1(m_operands.first()->evaluateSequence(context));
+ const Item::Iterator::Ptr it2(m_operands.at(1)->evaluateSequence(context));
+
+ while(true)
+ {
+ const Item item1(it1->next());
+ const Item item2(it2->next());
+
+ if(!item1)
+ {
+ if(item2)
+ return false;
+ else
+ return true;
+ }
+ else if(!item2)
+ {
+ if(item1)
+ return false;
+ else
+ return true;
+ }
+ else if(item1.isNode())
+ {
+ if(item2.isNode())
+ {
+ if(item1.asNode().isDeepEqual(item2.asNode()))
+ continue;
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+ else if(item2.isNode())
+ {
+ /* We know that item1 is not a node due to the check above. */
+ return false;
+ }
+ else if(flexibleCompare(item1, item2, context))
+ continue;
+ else if(BuiltinTypes::numeric->itemMatches(item1) &&
+ item1.as<Numeric>()->isNaN() &&
+ item2.as<Numeric>()->isNaN())
+ {
+ // TODO
+ /* Handle the specific NaN circumstances. item2 isn't checked whether it's of
+ * type numeric, since the AtomicComparator lookup would have failed if both weren't
+ * numeric. */
+ continue;
+ }
+ else
+ return false;
+ };
+}
+
+Expression::Ptr DeepEqualFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+ const ItemType::Ptr t1(m_operands.first()->staticType()->itemType());
+ const ItemType::Ptr t2(m_operands.at(1)->staticType()->itemType());
+ /* TODO This can be much more improved, and the optimizations should be moved
+ * to compress(). */
+
+ if(*CommonSequenceTypes::Empty == *t1)
+ {
+ if(*CommonSequenceTypes::Empty == *t2)
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else
+ return me;
+ }
+ else if(*CommonSequenceTypes::Empty == *t2)
+ {
+ if(*CommonSequenceTypes::Empty == *t1)
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else
+ return me;
+ }
+ else if(BuiltinTypes::node->xdtTypeMatches(t1) &&
+ BuiltinTypes::node->xdtTypeMatches(t2))
+ return me; /* We're comparing nodes. */
+ else if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1) &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t2))
+ {
+ prepareComparison(fetchComparator(t1, t2, context));
+ return me;
+ }
+ else
+ {
+ if ((BuiltinTypes::node->xdtTypeMatches(t1) && BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t2))
+ || (BuiltinTypes::node->xdtTypeMatches(t2) && BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1)))
+ {
+ /* One operand contains nodes and the other atomic values, or vice versa. They can never
+ * be identical. */
+ // TODO warn?
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ }
+ else
+ {
+ // TODO Warn?
+ return me;
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qdeepequalfn_p.h b/src/xmlpatterns/functions/qdeepequalfn_p.h
new file mode 100644
index 0000000000..6272b08e45
--- /dev/null
+++ b/src/xmlpatterns/functions/qdeepequalfn_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_DeepEqualFN_H
+#define Patternist_DeepEqualFN_H
+
+#include "qatomiccomparator_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:deep-equal()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DeepEqualFN : public FunctionCall,
+ public ComparisonPlatform<DeepEqualFN, false>
+ {
+ public:
+ inline DeepEqualFN() : ComparisonPlatform<DeepEqualFN, false>()
+ {
+ }
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return AtomicComparator::OperatorEqual;
+ }
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qdocumentfn.cpp b/src/xmlpatterns/functions/qdocumentfn.cpp
new file mode 100644
index 0000000000..02f28d9443
--- /dev/null
+++ b/src/xmlpatterns/functions/qdocumentfn.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qforclause_p.h"
+#include "qfunctionfactory_p.h"
+#include "qrangevariablereference_p.h"
+
+#include "qdocumentfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr DocumentFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* See the class documentation for the rewrite that we're doing here. */
+
+ /* Generate type checking code for our operands such that they match. */
+ typeCheckOperands(context);
+
+ const QSourceLocation myLocation(context->locationFor(this));
+ const FunctionFactory::Ptr functions(context->functionSignatures());
+
+ Expression::Ptr uriSource;
+
+ {
+ Expression::List distinctValuesArgs;
+ distinctValuesArgs.append(m_operands.first());
+
+ uriSource = functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::distinct_values),
+ distinctValuesArgs,
+ context,
+ this);
+ context->addLocation(uriSource.data(), myLocation);
+ }
+
+ const VariableSlotID rangeSlot = context->allocateRangeSlot();
+ const Expression::Ptr uriReference(new RangeVariableReference(uriSource, rangeSlot));
+ context->addLocation(uriReference.data(), myLocation);
+
+ Expression::List docArgs;
+
+ if(m_operands.count() == 2)
+ {
+ Expression::List baseUriArgs;
+ baseUriArgs.append(uriReference);
+ baseUriArgs.append(m_operands.at(1));
+
+ const Expression::Ptr fnBaseUri(functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::resolve_uri),
+ baseUriArgs,
+ context,
+ this));
+ context->addLocation(fnBaseUri.data(), myLocation);
+ docArgs.append(fnBaseUri);
+ }
+ else
+ docArgs.append(uriReference);
+
+ const Expression::Ptr fnDoc(functions->createFunctionCall(QXmlName(StandardNamespaces::fn, StandardLocalNames::doc),
+ docArgs,
+ context,
+ this));
+ context->addLocation(fnDoc.data(), myLocation);
+
+
+ Expression::Ptr newMe(new ForClause(rangeSlot,
+ uriSource,
+ fnDoc,
+ -1 /* We have no position variable. */));
+
+ Expression::Ptr oldMe(this);
+ rewrite(oldMe, newMe, context);
+ return newMe->typeCheck(context, reqType);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qdocumentfn_p.h b/src/xmlpatterns/functions/qdocumentfn_p.h
new file mode 100644
index 0000000000..74dcd31bca
--- /dev/null
+++ b/src/xmlpatterns/functions/qdocumentfn_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_DocumentFN_H
+#define Patternist_DocumentFN_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XSL-T's function <tt>fn:document()</tt>.
+ *
+ * @c fn:document() has no evaluation functions, because it rewrites
+ * itself to a set of expressions that is the implementation.
+ *
+ * The two-argument version:
+ *
+ * <tt>document($uris as item()*, $baseURINode as node()) as node()*</tt>
+ *
+ * is rewritten into:
+ *
+ * <tt>for $uri in distinct-values($uris)
+ * return doc(resolve-uri($uri, base-uri($baseURINode)))</tt>
+ *
+ * and the single version argument:
+ *
+ * <tt>document($uris as item()*) as node()*</tt>
+ *
+ * is rewritten into:
+ *
+ * <tt>for $uri in distinct-values($uris)
+ * return doc($uri)</tt>
+ *
+ * The distinct-values() call ensures the node deduplication and sorting,
+ * although it fails in the case that URIs resolve/directs in some way to
+ * the same document. Some of those cases can be solved by wrapping the
+ * whole expression with a node deduplication(conceptually the-for-loop/.).
+ * One advantage with distinct-values() over generating traditional node
+ * sorting/deduplication code is that the latter contains node sorting
+ * which is uecessary and can be hard to analyze away. distinct-values()
+ * doesn't have this problem due to its narrower task..
+ *
+ * This works without problems, assuming XTRE1160 is not raised and that
+ * the recover action instead is ignore. In the case XTRE1160 is raised,
+ * one must cater for this.
+ *
+ * In addition to this, both signatures has its first argument changed to
+ * type <tt>xs:string*</tt>, in order to generate atomization code.
+ *
+ * One notable thing is that the expression for $baseURINode, is moved
+ * inside a loop, and will be evaluated repeatedly, unless moved out as
+ * part of optimization.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @since 4.5
+ */
+ class DocumentFN : public FunctionCall
+ {
+ public:
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qelementavailablefn.cpp b/src/xmlpatterns/functions/qelementavailablefn.cpp
new file mode 100644
index 0000000000..853b2d0429
--- /dev/null
+++ b/src/xmlpatterns/functions/qelementavailablefn.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqnameconstructor_p.h"
+
+#include "qelementavailablefn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ElementAvailableFN::ElementAvailableFN() : m_xsltInstructions(allXSLTInstructions())
+{
+}
+
+QSet<QString> ElementAvailableFN::allXSLTInstructions()
+{
+ enum
+ {
+ StringSetSize = 27
+ };
+
+ QSet<QString> retval;
+ retval.reserve(StringSetSize);
+
+ /* Alphabetically. */
+ retval.insert(QLatin1String("analyze-string"));
+ retval.insert(QLatin1String("apply-imports"));
+ retval.insert(QLatin1String("apply-templates"));
+ retval.insert(QLatin1String("attribute"));
+ retval.insert(QLatin1String("attribute-set"));
+ retval.insert(QLatin1String("call-template"));
+ retval.insert(QLatin1String("character-map"));
+ retval.insert(QLatin1String("choose"));
+ retval.insert(QLatin1String("comment"));
+ retval.insert(QLatin1String("copy"));
+ retval.insert(QLatin1String("copy-of"));
+ retval.insert(QLatin1String("document"));
+ retval.insert(QLatin1String("element"));
+ retval.insert(QLatin1String("fallback"));
+ retval.insert(QLatin1String("for-each"));
+ retval.insert(QLatin1String("for-each-group"));
+ retval.insert(QLatin1String("if"));
+ retval.insert(QLatin1String("message"));
+ retval.insert(QLatin1String("namespace"));
+ retval.insert(QLatin1String("next-match"));
+ retval.insert(QLatin1String("number"));
+ retval.insert(QLatin1String("perform-sort"));
+ retval.insert(QLatin1String("processing-instruction"));
+ retval.insert(QLatin1String("result-document"));
+ retval.insert(QLatin1String("sequence"));
+ retval.insert(QLatin1String("text"));
+ retval.insert(QLatin1String("variable"));
+
+ Q_ASSERT(retval.count() == StringSetSize);
+ return retval;
+}
+
+bool ElementAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+ const QString stringName(arg.stringValue());
+
+ const QXmlName elementName(QNameConstructor::expandQName<DynamicContext::Ptr,
+ ReportContext::XTDE1440,
+ ReportContext::XTDE1440>(stringName,
+ context,
+ staticNamespaces(),
+ this,
+ false));
+
+ if(elementName.namespaceURI() != StandardNamespaces::xslt)
+ return false;
+
+ QString prefix;
+ QString localName;
+ XPathHelper::splitQName(stringName, prefix, localName);
+
+ return m_xsltInstructions.contains(localName);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qelementavailablefn_p.h b/src/xmlpatterns/functions/qelementavailablefn_p.h
new file mode 100644
index 0000000000..3ea1650fd5
--- /dev/null
+++ b/src/xmlpatterns/functions/qelementavailablefn_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ElementAvailableFN_H
+#define Patternist_ElementAvailableFN_H
+
+#include "qstaticnamespacescontainer_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:unparsed-text()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL
+ * Transformations (XSLT) Version 2.0, 16.2 unparsed-text</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @since 4.5
+ */
+ class ElementAvailableFN : public StaticNamespacesContainer
+ {
+ public:
+ ElementAvailableFN();
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ private:
+ static QSet<QString> allXSLTInstructions();
+ const QSet<QString> m_xsltInstructions;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qerrorfn.cpp b/src/xmlpatterns/functions/qerrorfn.cpp
new file mode 100644
index 0000000000..5cef1b6b30
--- /dev/null
+++ b/src/xmlpatterns/functions/qerrorfn.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+
+#include "qerrorfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ErrorFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ QString msg;
+
+ switch(m_operands.count())
+ {
+ case 0: /* No args. */
+ {
+ context->error(QtXmlPatterns::tr("%1 was called.").arg(formatFunction(context->namePool(), signature())),
+ ReportContext::FOER0000, this);
+ return Item();
+ }
+ case 3:
+ /* Fallthrough, we don't use the 'error object' param. */
+ case 2:
+ msg = m_operands.at(1)->evaluateSingleton(context).stringValue();
+ /* Fall through. */
+ case 1:
+ {
+ const QNameValue::Ptr qName(m_operands.first()->evaluateSingleton(context).as<QNameValue>());
+
+ if(qName)
+ context->error(msg, qName->qName(), this);
+ else
+ context->error(msg, ReportContext::FOER0000, this);
+
+ return Item();
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Invalid number of arguments passed to fn:error.");
+ return Item();
+ }
+ }
+}
+
+FunctionSignature::Ptr ErrorFN::signature() const
+{
+ const FunctionSignature::Ptr e(FunctionCall::signature());
+
+ if(m_operands.count() != 1)
+ return e;
+
+ FunctionSignature::Ptr nev(FunctionSignature::Ptr(new FunctionSignature(e->name(),
+ e->minimumArguments(),
+ e->maximumArguments(),
+ e->returnType(),
+ e->properties())));
+ const FunctionArgument::List args(e->arguments());
+ FunctionArgument::List nargs;
+ const QXmlName argName(StandardNamespaces::empty, StandardLocalNames::error);
+ nargs.append(FunctionArgument::Ptr(new FunctionArgument(argName, CommonSequenceTypes::ExactlyOneQName)));
+ nargs.append(args[1]);
+ nargs.append(args[2]);
+ nev->setArguments(nargs);
+
+ return nev;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qerrorfn_p.h b/src/xmlpatterns/functions/qerrorfn_p.h
new file mode 100644
index 0000000000..2598589a0c
--- /dev/null
+++ b/src/xmlpatterns/functions/qerrorfn_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ErrorFN_H
+#define Patternist_ErrorFN_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:error()</tt>.
+ *
+ * <tt>fn:error()</tt> is a bit special in that its first argument varies between
+ * the different signatures. This is implemented by changing the function
+ * signature if the amount of arguments is one.
+ *
+ * <tt>fn:error()</tt> has as return type the peculiar "none" type, which is handled by NoneType.
+ *
+ * @ingroup Patternist_functions
+ * @see CommonSequenceTypes::none
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-error">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 3 The Error Function</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ErrorFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual FunctionSignature::Ptr signature() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qfunctionargument.cpp b/src/xmlpatterns/functions/qfunctionargument.cpp
new file mode 100644
index 0000000000..63cf00f82a
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionargument.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfunctionargument_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+FunctionArgument::FunctionArgument(const QXmlName nameP,
+ const SequenceType::Ptr &typeP) : m_name(nameP),
+ m_type(typeP)
+{
+ Q_ASSERT(!nameP.isNull());
+ Q_ASSERT(typeP);
+}
+
+QXmlName FunctionArgument::name() const
+{
+ return m_name;
+}
+
+SequenceType::Ptr FunctionArgument::type() const
+{
+ return m_type;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qfunctionargument_p.h b/src/xmlpatterns/functions/qfunctionargument_p.h
new file mode 100644
index 0000000000..2703e565c5
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionargument_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_FunctionArgument_H
+#define Patternist_FunctionArgument_H
+
+#include <QList>
+#include <QSharedData>
+
+#include "qxmlname.h"
+#include "qsequencetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Carries meta data for a function argument as found in XPath's
+ * builtin functions and user declared functions in XQuery and XSL-T.
+ *
+ * @ingroup Patternist_functions
+ * @see VariableDeclaration
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class FunctionArgument : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<FunctionArgument> Ptr;
+ typedef QList<FunctionArgument::Ptr> List;
+
+ FunctionArgument(const QXmlName name,
+ const SequenceType::Ptr &type);
+
+ QXmlName name() const;
+ SequenceType::Ptr type() const;
+
+ private:
+ Q_DISABLE_COPY(FunctionArgument)
+ const QXmlName m_name;
+ const SequenceType::Ptr m_type;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qfunctionavailablefn.cpp b/src/xmlpatterns/functions/qfunctionavailablefn.cpp
new file mode 100644
index 0000000000..20c08fa506
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionavailablefn.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qdelegatingnamespaceresolver_p.h"
+#include "qinteger_p.h"
+#include "qqnameconstructor_p.h"
+
+#include "qfunctionavailablefn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item FunctionAvailableFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QString lexQName(m_operands.first()->evaluateSingleton(context).stringValue());
+
+ NamespaceResolver::Bindings override;
+ override.insert(StandardPrefixes::empty, m_defFuncNS);
+
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(staticNamespaces(), override));
+
+ const QXmlName name
+ (QNameConstructor::expandQName<DynamicContext::Ptr,
+ ReportContext::XTDE1400,
+ ReportContext::XTDE1400>(lexQName,
+ context,
+ resolver,
+ this));
+
+ xsInteger arity;
+
+ if(m_operands.count() == 2)
+ arity = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger();
+ else
+ arity = FunctionSignature::UnlimitedArity;
+
+ return Boolean::fromValue(m_functionFactory->isAvailable(context->namePool(), name, arity));
+}
+
+Expression::Ptr FunctionAvailableFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_functionFactory = context->functionSignatures();
+ Q_ASSERT(m_functionFactory);
+ m_defFuncNS = context->namePool()->allocateNamespace(context->defaultFunctionNamespace());
+ /* m_defFuncNS can be empty/null or an actual value. */
+
+ return StaticNamespacesContainer::typeCheck(context, reqType);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qfunctionavailablefn_p.h b/src/xmlpatterns/functions/qfunctionavailablefn_p.h
new file mode 100644
index 0000000000..b8ed8d2b8c
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionavailablefn_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_FunctionAvailableFN_H
+#define Patternist_FunctionAvailableFN_H
+
+#include "qstaticnamespacescontainer_p.h"
+#include "qfunctionfactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XSL-T 2.0's XPath function <tt>fn:function-available()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#function-function-available">XSL Transformations
+ * (XSLT) Version 2.0, 18.1.1 Testing Availability of Functions</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class FunctionAvailableFN : public StaticNamespacesContainer
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Reimplemented to store data from the @p context which is needed at runtime.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ private:
+ FunctionFactory::Ptr m_functionFactory;
+ QXmlName::NamespaceCode m_defFuncNS;
+ };
+
+QT_END_NAMESPACE
+}
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qfunctioncall.cpp b/src/xmlpatterns/functions/qfunctioncall.cpp
new file mode 100644
index 0000000000..edea72f624
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctioncall.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qcontextitem_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qfunctionsignature_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qcollationchecker_p.h"
+#include "qcommonnamespaces_p.h"
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SequenceType::List FunctionCall::expectedOperandTypes() const
+{
+ const FunctionArgument::List args(signature()->arguments());
+ FunctionArgument::List::const_iterator it(args.constBegin());
+ const FunctionArgument::List::const_iterator end(args.constEnd());
+ // TODO reserve/resize()
+ SequenceType::List result;
+
+ for(; it != end; ++it)
+ result.append((*it)->type());
+
+ return result;
+}
+
+Expression::Ptr FunctionCall::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* We don't cache properties() at some stages because it can be invalidated
+ * by the typeCheck(). */
+
+ const FunctionSignature::Arity maxArgs = signature()->maximumArguments();
+ /* We do this before the typeCheck() such that the appropriate conversions
+ * are applied to the ContextItem. */
+ if(m_operands.count() < maxArgs &&
+ has(UseContextItem))
+ {
+ m_operands.append(Expression::Ptr(new ContextItem()));
+ context->wrapExpressionWith(this, m_operands.last());
+ }
+
+ const Expression::Ptr me(UnlimitedContainer::typeCheck(context, reqType));
+ if(me != this)
+ return me;
+
+ const Properties props(properties());
+
+ if(props.testFlag(RewriteToEmptyOnEmpty) &&
+ *CommonSequenceTypes::Empty == *m_operands.first()->staticType()->itemType())
+ {
+ return EmptySequence::create(this, context);
+ }
+
+ if(props.testFlag(LastOperandIsCollation) &&
+ m_operands.count() == maxArgs)
+ {
+ m_operands.last() = Expression::Ptr(new CollationChecker(m_operands.last()));
+ context->wrapExpressionWith(this, m_operands.last());
+ }
+
+ return me;
+}
+
+void FunctionCall::setSignature(const FunctionSignature::Ptr &sign)
+{
+ m_signature = sign;
+}
+
+FunctionSignature::Ptr FunctionCall::signature() const
+{
+ Q_ASSERT(m_signature); /* It really should be set. */
+ return m_signature;
+}
+
+SequenceType::Ptr FunctionCall::staticType() const
+{
+ Q_ASSERT(m_signature);
+ if(has(EmptynessFollowsChild))
+ {
+ if(m_operands.isEmpty())
+ {
+ /* This is a function which uses the context item when having no arguments. */
+ return signature()->returnType();
+ }
+ const Cardinality card(m_operands.first()->staticType()->cardinality());
+ if(card.allowsEmpty())
+ return signature()->returnType();
+ else
+ {
+ /* Remove empty. */
+ return makeGenericSequenceType(signature()->returnType()->itemType(),
+ card & Cardinality::oneOrMore());
+ }
+ }
+ return signature()->returnType();
+}
+
+Expression::Properties FunctionCall::properties() const
+{
+ Q_ASSERT(m_signature);
+ return signature()->properties();
+}
+
+ExpressionVisitorResult::Ptr FunctionCall::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID FunctionCall::id() const
+{
+ Q_ASSERT(m_signature);
+ return m_signature->id();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qfunctioncall_p.h b/src/xmlpatterns/functions/qfunctioncall_p.h
new file mode 100644
index 0000000000..4d1123a07b
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctioncall_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_FunctionCall_H
+#define Patternist_FunctionCall_H
+
+#include "qunlimitedcontainer_p.h"
+#include "qfunctionsignature_p.h"
+#include "qxpathhelper_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for implementations of builtin functions.
+ *
+ * However, it doesn't handle user declared functions.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class FunctionCall : public UnlimitedContainer
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<FunctionCall> Ptr;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual void setSignature(const FunctionSignature::Ptr &sign);
+ virtual FunctionSignature::Ptr signature() const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual ID id() const;
+
+ private:
+ FunctionSignature::Ptr m_signature;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qfunctionfactory.cpp b/src/xmlpatterns/functions/qfunctionfactory.cpp
new file mode 100644
index 0000000000..6809bb2e3c
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactory.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfunctionsignature_p.h"
+
+#include "qfunctionfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+FunctionFactory::~FunctionFactory()
+{
+}
+
+bool FunctionFactory::isAvailable(const NamePool::Ptr &np,
+ const QXmlName name, const xsInteger arity)
+{
+ const FunctionSignature::Ptr sign(retrieveFunctionSignature(np, name));
+
+ if(sign)
+ return arity == FunctionSignature::UnlimitedArity || sign->isArityValid(arity);
+ else
+ return false;
+}
+
+bool FunctionFactory::hasSignature(const FunctionSignature::Ptr &signature) const
+{
+ const FunctionSignature::Hash signs(functionSignatures());
+ const FunctionSignature::Hash::const_iterator end(signs.constEnd());
+ FunctionSignature::Hash::const_iterator it(signs.constBegin());
+
+ for(; it != end; ++it)
+ {
+ if(*(*it) == *signature)
+ return true;
+ }
+
+ return false;
+}
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qfunctionfactory_p.h b/src/xmlpatterns/functions/qfunctionfactory_p.h
new file mode 100644
index 0000000000..e0a7d4a03c
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactory_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+
+#ifndef Patternist_FunctionFactory_H
+#define Patternist_FunctionFactory_H
+
+#include <QHash>
+#include <QSharedData>
+
+#include "qexpression_p.h"
+#include "qfunctionsignature_p.h"
+#include "qprimitives_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short An entry point for looking up and creating FunctionCall instances.
+ *
+ * @ingroup Patternist_functions
+ * @see <a href ="http://www.w3.org/TR/xpath-functions/">XQuery 1.0
+ * and XPath 2.0 Functions and Operators</a>
+ * @see <a href="http://www.w3.org/TR/xpath20/#dt-function-signature">XML Path
+ * Language (XPath) 2.0, Definition: Function signatures</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class FunctionFactory : public QSharedData
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<FunctionFactory> Ptr;
+ typedef QList<FunctionFactory::Ptr> List;
+
+ virtual ~FunctionFactory();
+
+ /**
+ * Creates a function call implementation.
+ *
+ * A FunctionFactory represents a set of functions, which it
+ * is able to instantiate and to serve FunctionSignatures for. Conventionally,
+ * a FunctionFactory per namespace exists.
+ *
+ * @note This function should not issue any error unless it is absolutely
+ * confident that the error cannot be fixed in another way. For example, in
+ * some cases it might be that a function is available in another FunctionFactory
+ * and it would therefore be wrong to issue an error signalling that no function
+ * by that @p name exists, but leave that to the callee.
+ * @param name the name of the function to create. In Clark syntax, this could
+ * for example be {http://www.w3.org/2005/04/xpath-functions}lower-case
+ * @param arguments the function's operands
+ * @param context the usual StaticContext which supplies compile time data
+ * and reporting functionality.
+ * @param r the SourceLocationReflection that identifies the callsite.
+ * @returns an instance of Expression which is the function implementation
+ * for @p name. Or, a static error was raised.
+ */
+ virtual Expression::Ptr createFunctionCall(const QXmlName name,
+ const Expression::List &arguments,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r) = 0;
+
+ /**
+ * Determines whether a function with the name @p name and arity @p arity
+ * is available. The implementation operates on the result of
+ * retrieveFunctionSignature() to determine the result.
+ *
+ * @param np the NamePool.
+ * @param name the name of the function. For example fn:string-join.
+ * @param arity the number of arguments the function must have.
+ */
+ virtual bool isAvailable(const NamePool::Ptr &np,
+ const QXmlName name,
+ const xsInteger arity);
+
+ virtual FunctionSignature::Hash functionSignatures() const = 0;
+
+ /**
+ * Determines whether this FunctionFactory contains the function signature
+ * @p signature.
+ *
+ * The implementation uses functionSignatures().
+ */
+ bool hasSignature(const FunctionSignature::Ptr &signature) const;
+
+ protected:
+ /**
+ * @short This constructor cannot be removed, because it can't be synthesized, for
+ * some reason.
+ */
+ inline FunctionFactory()
+ {
+ }
+
+ /**
+ * This is a convenience function for sub-classes. It retrieves the
+ * function signature for function with name @p name.
+ *
+ * According to the specifications are function signatures identified by their
+ * name and arity, but currently is the arity not part of the signature.
+ *
+ * If no function could be found for the given name, @c null is returned.
+ */
+ virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) = 0;
+
+ private:
+ Q_DISABLE_COPY(FunctionFactory)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qfunctionfactorycollection.cpp b/src/xmlpatterns/functions/qfunctionfactorycollection.cpp
new file mode 100644
index 0000000000..00856f4bb7
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactorycollection.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbasictypesfactory_p.h"
+#include "qconstructorfunctionsfactory_p.h"
+#include "qfunctioncall_p.h"
+#include "qxpath10corefunctions_p.h"
+#include "qxpath20corefunctions_p.h"
+#include "qxslt20corefunctions_p.h"
+
+#include "qfunctionfactorycollection_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr FunctionFactoryCollection::createFunctionCall(const QXmlName name,
+ const Expression::List &arguments,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+{
+ const_iterator it;
+ const_iterator e(constEnd());
+ Expression::Ptr function;
+
+ for(it = constBegin(); it != e; ++it)
+ {
+ function = (*it)->createFunctionCall(name, arguments, context, r);
+
+ if(function)
+ break;
+ }
+
+ return function;
+}
+
+bool FunctionFactoryCollection::isAvailable(const NamePool::Ptr &np, const QXmlName name, const xsInteger arity)
+{
+ const_iterator it;
+ const_iterator e(constEnd());
+
+ for(it = constBegin(); it != e; ++it)
+ if((*it)->isAvailable(np, name, arity))
+ return true;
+
+ return false;
+}
+
+FunctionSignature::Hash FunctionFactoryCollection::functionSignatures() const
+{
+ /* We simply grab the function signatures for each library, and
+ * put them all in one list. */
+
+ const const_iterator e(constEnd());
+ FunctionSignature::Hash result;
+
+ for(const_iterator it(constBegin()); it != e; ++it)
+ {
+ const FunctionSignature::Hash::const_iterator e2((*it)->functionSignatures().constEnd());
+ FunctionSignature::Hash::const_iterator sit((*it)->functionSignatures().constBegin());
+
+ for(; sit != e2; ++sit)
+ result.insert(sit.key(), sit.value());
+ }
+
+ return result;
+}
+
+FunctionSignature::Ptr FunctionFactoryCollection::retrieveFunctionSignature(const NamePool::Ptr &, const QXmlName name)
+{
+ return functionSignatures().value(name);
+}
+
+FunctionFactory::Ptr FunctionFactoryCollection::xpath10Factory()
+{
+ /* We don't use a global static for caching this, because AbstractFunctionFactory
+ * stores state specific to the NamePool, when being used. */
+ return FunctionFactory::Ptr(new XPath10CoreFunctions());
+}
+
+FunctionFactory::Ptr FunctionFactoryCollection::xpath20Factory(const NamePool::Ptr &np)
+{
+ /* We don't use a global static for caching this, because AbstractFunctionFactory
+ * stores state specific to the NamePool, when being used. */
+ const FunctionFactoryCollection::Ptr fact(new FunctionFactoryCollection());
+ fact->append(xpath10Factory());
+ fact->append(FunctionFactory::Ptr(new XPath20CoreFunctions()));
+ fact->append(FunctionFactory::Ptr(
+ new ConstructorFunctionsFactory(np, BasicTypesFactory::self(np))));
+ return fact;
+}
+
+FunctionFactory::Ptr FunctionFactoryCollection::xslt20Factory(const NamePool::Ptr &np)
+{
+ const FunctionFactory::Ptr retval(xpath20Factory(np));
+ static_cast<FunctionFactoryCollection *>(retval.data())->append(FunctionFactory::Ptr(new XSLT20CoreFunctions()));
+ return retval;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qfunctionfactorycollection_p.h b/src/xmlpatterns/functions/qfunctionfactorycollection_p.h
new file mode 100644
index 0000000000..f83aaacb01
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionfactorycollection_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+
+#ifndef Patternist_FunctionFactoryCollection_H
+#define Patternist_FunctionFactoryCollection_H
+
+#include "qfunctionfactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A FunctionFactoryCollection instance is a FunctionFactory in its own right,
+ * but looks in its contained collection of factories for requested functions.
+ *
+ * @note the order of adding function libraries is significant.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class Q_AUTOTEST_EXPORT FunctionFactoryCollection: public FunctionFactory
+ , public FunctionFactory::List
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<FunctionFactoryCollection> Ptr;
+
+ /**
+ * Creates a function call node.
+ */
+ virtual Expression::Ptr createFunctionCall(const QXmlName,
+ const Expression::List &arguments,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r);
+ virtual bool isAvailable(const NamePool::Ptr &np, const QXmlName name, const xsInteger arity);
+
+ virtual FunctionSignature::Hash functionSignatures() const;
+
+ virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name);
+
+ /**
+ * @return a FunctionFactory containing all core functions and constructor
+ * functions required for XPath 2.. The functions specified for XQuery 1.0
+ * are the same as for XPath 2.0 so this FunctionFactory work for XQuery
+ * as well.
+ */
+ static FunctionFactory::Ptr xpath20Factory(const NamePool::Ptr &np);
+
+ /**
+ * @return a FunctionFactory containing all core functions required for XPath 1.0.
+ */
+ static FunctionFactory::Ptr xpath10Factory();
+
+ /**
+ * @return a FunctionFactory containing all core functions required for XSL-T 2.0
+ * functions.
+ */
+ static FunctionFactory::Ptr xslt20Factory(const NamePool::Ptr &np);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qfunctionsignature.cpp b/src/xmlpatterns/functions/qfunctionsignature.cpp
new file mode 100644
index 0000000000..15f9cffdd9
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionsignature.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxmlname.h"
+
+#include "qfunctionsignature_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+FunctionSignature::FunctionSignature(const QXmlName nameP,
+ const Arity minArgs,
+ const Arity maxArgs,
+ const SequenceType::Ptr &returnTypeP,
+ const Expression::Properties props,
+ const Expression::ID idP) : CallTargetDescription(nameP)
+ , m_minArgs(minArgs)
+ , m_maxArgs(maxArgs)
+ , m_returnType(returnTypeP)
+ , m_arguments()
+ , m_props(props)
+ , m_id(idP)
+{
+ Q_ASSERT(minArgs <= maxArgs || maxArgs == FunctionSignature::UnlimitedArity);
+ Q_ASSERT(m_maxArgs >= -1);
+ Q_ASSERT(returnTypeP);
+}
+
+void FunctionSignature::appendArgument(const QXmlName::LocalNameCode nameP,
+ const SequenceType::Ptr &type)
+{
+ Q_ASSERT(type);
+
+ m_arguments.append(FunctionArgument::Ptr(new FunctionArgument(QXmlName(StandardNamespaces::empty, nameP), type)));
+}
+
+QString FunctionSignature::displayName(const NamePool::Ptr &np) const
+{
+ QString result;
+ result += np->displayName(name());
+ result += QLatin1Char('(');
+
+ FunctionArgument::List::const_iterator it(m_arguments.constBegin());
+ const FunctionArgument::List::const_iterator end(m_arguments.constEnd());
+
+ if(it != end)
+ {
+ while(true)
+ {
+ result += QLatin1Char('$');
+ result += np->displayName((*it)->name());
+ result += QLatin1String(" as ");
+ result += (*it)->type()->displayName(np);
+
+ ++it;
+ if(it == end)
+ break;
+
+ result += QLatin1String(", ");
+ }
+ }
+
+ if(m_maxArgs == FunctionSignature::UnlimitedArity)
+ result += QLatin1String(", ...");
+
+ result += QLatin1String(") as ");
+ result += m_returnType->displayName(np);
+
+ return result;
+}
+
+bool FunctionSignature::operator==(const FunctionSignature &other) const
+{
+ return name() == other.name() &&
+ isArityValid(other.maximumArguments()) &&
+ isArityValid(other.minimumArguments());
+}
+
+void FunctionSignature::setArguments(const FunctionArgument::List &args)
+{
+ m_arguments = args;
+}
+
+FunctionArgument::List FunctionSignature::arguments() const
+{
+ return m_arguments;
+}
+
+bool FunctionSignature::isArityValid(const xsInteger arity) const
+{
+ return arity >= m_minArgs && arity <= m_maxArgs;
+}
+
+FunctionSignature::Arity FunctionSignature::minimumArguments() const
+{
+ return m_minArgs;
+}
+
+FunctionSignature::Arity FunctionSignature::maximumArguments() const
+{
+ return m_maxArgs;
+}
+
+SequenceType::Ptr FunctionSignature::returnType() const
+{
+ return m_returnType;
+}
+
+Expression::Properties FunctionSignature::properties() const
+{
+ return m_props;
+}
+
+Expression::ID FunctionSignature::id() const
+{
+ return m_id;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qfunctionsignature_p.h b/src/xmlpatterns/functions/qfunctionsignature_p.h
new file mode 100644
index 0000000000..4dcd4ccabe
--- /dev/null
+++ b/src/xmlpatterns/functions/qfunctionsignature_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_FunctionSignature_H
+#define Patternist_FunctionSignature_H
+
+template<typename Key, typename Value> class QHash;
+template<typename T> class QList;
+
+#include <QSharedData>
+
+#include "qcalltargetdescription_p.h"
+#include "qexpression_p.h"
+#include "qfunctionargument_p.h"
+#include "qpatternistlocale_p.h"
+#include "qprimitives_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents the signature of an XPath function.
+ *
+ * FunctionSignature represents and allows inspection of a function signature,
+ * such as <tt>fn:string-join($arg1 as xs:string*, $arg2 as xs:string) as xs:string</tt>.
+ * No XPath related languages allows polymorphism on the type of the arguments, only the
+ * amount(arity) of the arguments. For example, <tt>fn:string() as xs:string</tt> and
+ * <tt>fn:string($arg as item()?) as xs:string</tt> can happily co-exist, but
+ * <tt>fn:string($arg as item()?) as xs:string</tt> and
+ * <tt>fn:string($arg as xs:anyAtomicType?) as xs:string</tt> would be an error. This
+ * fact is reflected by FunctionSignature that if minimumArguments() and maximumArguments()
+ * are not equal, it means that this FunctionSignature represents several
+ * function signatures.
+ *
+ * @ingroup Patternist_functions
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 1.4 Function Signatures and Descriptions</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Arity">Wikipedia, the free encyclopedia, Arity</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class Q_AUTOTEST_EXPORT FunctionSignature : public CallTargetDescription
+ {
+ public:
+ enum
+ {
+ /**
+ * Flags the function as allowing an unlimited amount of arguments.
+ */
+ UnlimitedArity = -1
+ };
+
+ typedef QExplicitlySharedDataPointer<FunctionSignature> Ptr;
+ typedef QHash<QXmlName, FunctionSignature::Ptr> Hash;
+ typedef QList<FunctionSignature::Ptr> List;
+
+ /**
+ * A number which tells the amount of arguments a function has.
+ */
+ typedef qint16 Arity;
+
+ FunctionSignature(const QXmlName name,
+ const Arity minArgs,
+ const Arity maxArgs,
+ const SequenceType::Ptr &returnType,
+ const Expression::Properties chars = Expression::Properties(),
+ const Expression::ID id = Expression::IDIgnorableExpression);
+
+ void setArguments(const FunctionArgument::List &args);
+ FunctionArgument::List arguments() const;
+
+ /**
+ * This is a convenience function. Calling this once, is equal to
+ * calling setArguments() with a list containing a FunctionsArgument with name @p name
+ * and type @p type.
+ */
+ void appendArgument(const QXmlName::LocalNameCode name,
+ const SequenceType::Ptr &type);
+
+ /**
+ * Checks whether @p arity is within the range of allowed count of arguments. For example,
+ * when the minimum arguments is 1 and maximum arguments 2, @c false will be returned for
+ * passing 0 while @c true will be returned when 2 is passed.
+ */
+ bool isArityValid(const xsInteger arity) const;
+
+ Arity minimumArguments() const;
+ Arity maximumArguments() const;
+
+ /**
+ * The return type of this function signature. For example, if the represented function
+ * signature is <tt>fn:string() as xs:string</tt>, the return type is <tt>xs:string</tt>.
+ */
+ SequenceType::Ptr returnType() const;
+
+ /**
+ * The properties that the corresponding FunctionCall instance should return in
+ * Expression::properties().
+ */
+ Expression::Properties properties() const;
+
+ /**
+ * Determines whether this FunctionSignature is equal to @p other, taking
+ * into account XPath's function polymorphism. @p other is equal to this
+ * FunctionSignature if their name() instances are equal, and that the maximumArguments()
+ * and minimumArguments() arguments of @p other are allowed, as per isArityValid().
+ *
+ * In other words, this equalness operator can return @c true for different
+ * signatures, but it do make sense since a FunctionSignature can represent
+ * multiple signatures.
+ *
+ * @returns @c true if this FunctionSignature is equal to @p other, otherwise @c false
+ */
+ bool operator==(const FunctionSignature &other) const;
+
+ /**
+ * Builds a string representation for this function signature. The syntax
+ * used is the one used in the XQuery. It looks like this:
+ *
+ * <tt>prefix:function-name($parameter-name as parameter-type, ...) as return-type</tt>
+ *
+ * The prefix used for the name is conventional. For example, for constructor functions
+ * is @c xs used.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 1.4 Function Signatures and Descriptions</a>
+ */
+ QString displayName(const NamePool::Ptr &np) const;
+
+ /**
+ * The ID that the corresponding FunctionCall instance should return in
+ * Expression::id().
+ */
+ Expression::ID id() const;
+
+ private:
+ Q_DISABLE_COPY(FunctionSignature)
+
+ const Arity m_minArgs;
+ const Arity m_maxArgs;
+ const SequenceType::Ptr m_returnType;
+ FunctionArgument::List m_arguments;
+ const Expression::Properties m_props;
+ const Expression::ID m_id;
+ };
+
+ /**
+ * @short Formats FunctionSignature.
+ */
+ static inline QString formatFunction(const NamePool::Ptr &np, const FunctionSignature::Ptr &func)
+ {
+ return QLatin1String("<span class='XQuery-function'>") +
+ escape(func->displayName(np)) +
+ QLatin1String("</span>");
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qgenerateidfn.cpp b/src/xmlpatterns/functions/qgenerateidfn.cpp
new file mode 100644
index 0000000000..c1913da591
--- /dev/null
+++ b/src/xmlpatterns/functions/qgenerateidfn.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicstring_p.h"
+
+#include "qgenerateidfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item GenerateIDFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QXmlNodeModelIndex &node = m_operands.first()->evaluateSingleton(context).asNode();
+
+ if(node.isNull())
+ return AtomicString::fromValue(QString());
+
+ return AtomicString::fromValue(QLatin1Char('T')
+ + QString::number(qptrdiff(node.model()))
+ + QString::number(qptrdiff(node.internalPointer()))
+ + QString::number(node.additionalData()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qgenerateidfn_p.h b/src/xmlpatterns/functions/qgenerateidfn_p.h
new file mode 100644
index 0000000000..54b94cd5ce
--- /dev/null
+++ b/src/xmlpatterns/functions/qgenerateidfn_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_GenerateIDFN_H
+#define Patternist_GenerateIDFN_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:generate-id()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @see <a href="http://www.w3.org/TR/xslt20/#generate-id">XSL
+ * Transformations (XSLT) Version 2.0, 16.6.4 generate-id</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @since 4.5
+ */
+ class GenerateIDFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qnodefns.cpp b/src/xmlpatterns/functions/qnodefns.cpp
new file mode 100644
index 0000000000..5230a6c7ac
--- /dev/null
+++ b/src/xmlpatterns/functions/qnodefns.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloat_p.h"
+#include "qanyuri_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+#include "qatomicstring_p.h"
+
+#include "qnodefns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item NameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item node(m_operands.first()->evaluateSingleton(context));
+
+ if(node)
+ {
+ const QXmlName name(node.asNode().name());
+
+ if(name.isNull())
+ return CommonValues::EmptyString;
+ else
+ return AtomicString::fromValue(context->namePool()->toLexical(name));
+ }
+ else
+ return CommonValues::EmptyString;
+}
+
+Item LocalNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item node(m_operands.first()->evaluateSingleton(context));
+
+ if(node)
+ {
+ const QXmlName name(node.asNode().name());
+
+ if(name.isNull())
+ return CommonValues::EmptyString;
+ else
+ return AtomicString::fromValue(context->namePool()->stringForLocalName(name.localName()));
+ }
+ else
+ return CommonValues::EmptyString;
+}
+
+Item NamespaceURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item node(m_operands.first()->evaluateSingleton(context));
+
+ if(node)
+ {
+ const QXmlName name(node.asNode().name());
+
+ if(name.isNull())
+ return CommonValues::EmptyAnyURI;
+ else
+ return toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(name.namespaceURI())));
+ }
+ else
+ return CommonValues::EmptyAnyURI;
+}
+
+Item NumberFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(!item)
+ return CommonValues::DoubleNaN;
+
+ const Item val(cast(item, context));
+ Q_ASSERT(val);
+
+ if(val.as<AtomicValue>()->hasError())
+ return CommonValues::DoubleNaN;
+ else
+ return val;
+}
+
+Expression::Ptr NumberFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+ const ItemType::Ptr sourceType(m_operands.first()->staticType()->itemType());
+
+ if(BuiltinTypes::xsDouble->xdtTypeMatches(sourceType))
+ {
+ /* The operand is already xs:double, no need for fn:number(). */
+ return m_operands.first()->typeCheck(context, reqType);
+ }
+ else if(prepareCasting(context, sourceType))
+ return me;
+ else
+ {
+ /* Casting to xs:double will never succeed and we would always return NaN.*/
+ return wrapLiteral(CommonValues::DoubleNaN, context, this)->typeCheck(context, reqType);
+ }
+}
+
+bool LangFN::isLangMatch(const QString &candidate, const QString &toMatch)
+{
+ if(QString::compare(candidate, toMatch, Qt::CaseInsensitive) == 0)
+ return true;
+
+ return candidate.startsWith(toMatch, Qt::CaseInsensitive)
+ && candidate.length() > toMatch.length()
+ && candidate.at(toMatch.length()) == QLatin1Char('-');
+}
+
+Item LangFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item langArg(m_operands.first()->evaluateSingleton(context));
+ const QString lang(langArg ? langArg.stringValue() : QString());
+
+ const QXmlName xmlLang(StandardNamespaces::xml, StandardLocalNames::lang, StandardPrefixes::xml);
+ const QXmlNodeModelIndex langNode(m_operands.at(1)->evaluateSingleton(context).asNode());
+
+ const QXmlNodeModelIndex::Iterator::Ptr ancestors(langNode.iterate(QXmlNodeModelIndex::AxisAncestorOrSelf));
+ QXmlNodeModelIndex ancestor(ancestors->next());
+
+ while(!ancestor.isNull())
+ {
+ const QXmlNodeModelIndex::Iterator::Ptr attributes(ancestor.iterate(QXmlNodeModelIndex::AxisAttribute));
+ QXmlNodeModelIndex attribute(attributes->next());
+
+ while(!attribute.isNull())
+ {
+ Q_ASSERT(attribute.kind() == QXmlNodeModelIndex::Attribute);
+
+ if(attribute.name() == xmlLang)
+ {
+ if(isLangMatch(attribute.stringValue(), lang))
+ return CommonValues::BooleanTrue;
+ else
+ return CommonValues::BooleanFalse;
+ }
+
+ attribute = attributes->next();
+ }
+
+ ancestor = ancestors->next();
+ }
+
+ return CommonValues::BooleanFalse;
+}
+
+Item RootFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+
+ if(arg)
+ return arg.asNode().root();
+ else
+ return Item();
+}
+
+SequenceType::Ptr RootFN::staticType() const
+{
+ if(m_operands.isEmpty())
+ return makeGenericSequenceType(BuiltinTypes::node, Cardinality::exactlyOne());
+ else
+ return makeGenericSequenceType(BuiltinTypes::node, m_operands.first()->staticType()->cardinality().toWithoutMany());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qnodefns_p.h b/src/xmlpatterns/functions/qnodefns_p.h
new file mode 100644
index 0000000000..e762fe812f
--- /dev/null
+++ b/src/xmlpatterns/functions/qnodefns_p.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_NodeFNs_H
+#define Patternist_NodeFNs_H
+
+#include "qfunctioncall_p.h"
+#include "qcastingplatform_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#node-functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 14 Functions and Operators on Nodes</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:name()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:local-name()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class LocalNameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:namespace-uri()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NamespaceURIFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:number()</tt>.
+ *
+ * NumberFN uses CastingPlatform for performing the actual casting.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NumberFN : public FunctionCall,
+ public CastingPlatform<NumberFN, false>
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Overridden in order to call CastingPlatform::prepareCasting(). It also
+ * implements the optimization of rewriting to its operand if its
+ * type is xs:double(since the <tt>fn:number()</tt> call is in that case superflorous).
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always BuiltinTypes::xsDouble.
+ */
+ inline ItemType::Ptr targetType() const
+ {
+ return BuiltinTypes::xsDouble;
+ }
+ };
+
+ /**
+ * @short Implements the function <tt>fn:lang()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class LangFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ private:
+ static inline bool isLangMatch(const QString &candidate, const QString &toMatch);
+ };
+
+ /**
+ * @short Implements the function <tt>fn:root()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class RootFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ /**
+ * Infers its cardinality from the argument.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qnumericfns.cpp b/src/xmlpatterns/functions/qnumericfns.cpp
new file mode 100644
index 0000000000..73e7eda60f
--- /dev/null
+++ b/src/xmlpatterns/functions/qnumericfns.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonvalues_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qschemanumeric_p.h"
+
+#include "qnumericfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item FloorFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item num(m_operands.first()->evaluateSingleton(context));
+
+ if(!num)
+ return Item();
+
+ return toItem(num.as<Numeric>()->floor());
+}
+
+Item AbsFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item num(m_operands.first()->evaluateSingleton(context));
+
+ if(!num)
+ return Item();
+
+ return toItem(num.as<Numeric>()->abs());
+}
+
+Item RoundFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item num(m_operands.first()->evaluateSingleton(context));
+
+ if(!num)
+ return Item();
+
+ return toItem(num.as<Numeric>()->round());
+}
+
+Item CeilingFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item num(m_operands.first()->evaluateSingleton(context));
+
+ if(!num)
+ return Item();
+
+ return toItem(num.as<Numeric>()->ceiling());
+}
+
+Item RoundHalfToEvenFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item num(m_operands.first()->evaluateSingleton(context));
+
+ if(!num)
+ return Item();
+
+ xsInteger scale = 0;
+
+ if(m_operands.count() == 2)
+ scale = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger();
+
+ return toItem(num.as<Numeric>()->roundHalfToEven(scale));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qnumericfns_p.h b/src/xmlpatterns/functions/qnumericfns_p.h
new file mode 100644
index 0000000000..51c9b71173
--- /dev/null
+++ b/src/xmlpatterns/functions/qnumericfns_p.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_NumericFNs_H
+#define Patternist_NumericFNs_H
+
+#include "qaggregator_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#numeric-value-functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 6.4 Functions on Numeric Values</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:floor()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class FloorFN : public Aggregator
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:abs()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class AbsFN : public Aggregator
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:round()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class RoundFN : public Aggregator
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:ceiling()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CeilingFN : public Aggregator
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:round-half-to-even()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-round-half-to-even">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 6.4.5 fn:round-half-to-even</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class RoundHalfToEvenFN : public Aggregator
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qpatternmatchingfns.cpp b/src/xmlpatterns/functions/qpatternmatchingfns.cpp
new file mode 100644
index 0000000000..f930955e40
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternmatchingfns.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qpatternistlocale_p.h"
+#include "qatomicstring_p.h"
+
+#include "qpatternmatchingfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+MatchesFN::MatchesFN() : PatternPlatform(2)
+{
+}
+
+Item MatchesFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QRegExp regexp(pattern(context));
+ QString input;
+
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+ if(arg)
+ input = arg.stringValue();
+
+ return Boolean::fromValue(input.contains(regexp));
+}
+
+ReplaceFN::ReplaceFN() : PatternPlatform(3)
+{
+}
+
+Item ReplaceFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QRegExp regexp(pattern(context));
+ QString input;
+
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+ if(arg)
+ input = arg.stringValue();
+
+ const QString replacement(m_replacementString.isNull() ? parseReplacement(regexp.numCaptures(), context)
+ : m_replacementString);
+
+
+ return AtomicString::fromValue(input.replace(regexp, replacement));
+}
+
+QString ReplaceFN::errorAtEnd(const char ch)
+{
+ return QtXmlPatterns::tr("%1 must be followed by %2 or %3, not at "
+ "the end of the replacement string.")
+ .arg(formatKeyword(QLatin1Char(ch)))
+ .arg(formatKeyword(QLatin1Char('\\')))
+ .arg(formatKeyword(QLatin1Char('$')));
+}
+
+QString ReplaceFN::parseReplacement(const int,
+ const DynamicContext::Ptr &context) const
+{
+ // TODO what if there is no groups, can one rewrite to the replacement then?
+ const QString input(m_operands.at(2)->evaluateSingleton(context).stringValue());
+
+ QString retval;
+ retval.reserve(input.size());
+ const int len = input.length();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QChar ch(input.at(i));
+ switch(ch.toAscii())
+ {
+ case '$':
+ {
+ /* QRegExp uses '\' as opposed to '$' for marking sub groups. */
+ retval.append(QLatin1Char('\\'));
+
+ ++i;
+ if(i == len)
+ {
+ context->error(errorAtEnd('$'), ReportContext::FORX0004, this);
+ return QString();
+ }
+
+ const QChar nextCh(input.at(i));
+ if(nextCh.isDigit())
+ retval.append(nextCh);
+ else
+ {
+ context->error(QtXmlPatterns::tr("In the replacement string, %1 must be "
+ "followed by at least one digit when not escaped.")
+ .arg(formatKeyword(QLatin1Char('$'))),
+ ReportContext::FORX0004, this);
+ return QString();
+ }
+
+ break;
+ }
+ case '\\':
+ {
+ ++i;
+ if(i == len)
+ {
+ /* error, we've reached the end. */;
+ context->error(errorAtEnd('\\'), ReportContext::FORX0004, this);
+ }
+
+ const QChar nextCh(input.at(i));
+ if(nextCh == QLatin1Char('\\') || nextCh == QLatin1Char('$'))
+ {
+ retval.append(ch);
+ break;
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("In the replacement string, %1 can only be used to "
+ "escape itself or %2, not %3")
+ .arg(formatKeyword(QLatin1Char('\\')))
+ .arg(formatKeyword(QLatin1Char('$')))
+ .arg(formatKeyword(nextCh)),
+ ReportContext::FORX0004, this);
+ return QString();
+ }
+ }
+ default:
+ retval.append(ch);
+ }
+ }
+
+ return retval;
+}
+
+Expression::Ptr ReplaceFN::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PatternPlatform::compress(context));
+
+ if(me != this)
+ return me;
+
+ if(m_operands.at(2)->is(IDStringValue))
+ {
+ const int capt = captureCount();
+ if(capt == -1)
+ return me;
+ else
+ m_replacementString = parseReplacement(captureCount(), context->dynamicContext());
+ }
+
+ return me;
+}
+
+TokenizeFN::TokenizeFN() : PatternPlatform(2)
+{
+}
+
+/**
+ * Used by QAbstractXmlForwardIterator.
+ */
+static inline bool qIsForwardIteratorEnd(const QString &item)
+{
+ return item.isNull();
+}
+
+Item TokenizeFN::mapToItem(const QString &subject, const DynamicContext::Ptr &) const
+{
+ return AtomicString::fromValue(subject);
+}
+
+Item::Iterator::Ptr TokenizeFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+ if(!arg)
+ return CommonValues::emptyIterator;
+
+ const QString input(arg.stringValue());
+ if(input.isEmpty())
+ return CommonValues::emptyIterator;
+
+ const QRegExp regExp(pattern(context));
+ const QStringList result(input.split(regExp, QString::KeepEmptyParts));
+
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ makeListIterator(result),
+ DynamicContext::Ptr());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qpatternmatchingfns_p.h b/src/xmlpatterns/functions/qpatternmatchingfns_p.h
new file mode 100644
index 0000000000..50bb45041b
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternmatchingfns_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_PatternMatchingFNs_H
+#define Patternist_PatternMatchingFNs_H
+
+#include "qpatternplatform_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#string.match">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 7.6 AtomicString Functions that Use Pattern Matching</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:matches()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class MatchesFN : public PatternPlatform
+ {
+ public:
+ MatchesFN();
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:replace()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ReplaceFN : public PatternPlatform
+ {
+ public:
+ ReplaceFN();
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ /**
+ * Overridden to attempt to pre-compile the replacement string.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ /**
+ * @short Centralizes the translation string.
+ */
+ static inline QString errorAtEnd(const char ch);
+
+ /**
+ * Reads the string in the third argument and converts it to a a QRegExp compatible
+ * replacement string, containing sub-group references and so forth.
+ */
+ QString parseReplacement(const int captureCount,
+ const DynamicContext::Ptr &context) const;
+
+ QString m_replacementString;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:tokenize()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class TokenizeFN : public PatternPlatform
+ {
+ public:
+ TokenizeFN();
+ inline Item mapToItem(const QString &subject, const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const TokenizeFN> ConstPtr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qpatternplatform.cpp b/src/xmlpatterns/functions/qpatternplatform.cpp
new file mode 100644
index 0000000000..0052a0783c
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternplatform.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "qpatternistlocale_p.h"
+
+#include "qpatternplatform_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ /**
+ * @short Used internally by PatternPlatform and describes
+ * a flag that affects how a pattern is treated.
+ *
+ * The member variables aren't declared @c const, in order
+ * to make the synthesized assignment operator and copy constructor work.
+ *
+ * @ingroup Patternist_utils
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class PatternFlag
+ {
+ public:
+ typedef QHash<QChar, PatternFlag> Hash;
+
+ inline PatternFlag() : flag(PatternPlatform::NoFlags)
+ {
+ }
+
+ inline PatternFlag(const PatternPlatform::Flag opt,
+ const QString &descr) : flag(opt),
+ description(descr)
+ {
+ }
+
+ PatternPlatform::Flag flag;
+ QString description;
+
+ static inline Hash flagDescriptions();
+ };
+}
+
+static inline PatternFlag::Hash flagDescriptions()
+{
+ PatternFlag::Hash retval;
+
+ retval.insert(QChar(QLatin1Char('s')),
+ PatternFlag(PatternPlatform::DotAllMode,
+ QtXmlPatterns::tr("%1 matches newline characters").arg(formatKeyword(QLatin1Char('.')))));
+
+ retval.insert(QChar(QLatin1Char('m')),
+ PatternFlag(PatternPlatform::MultiLineMode,
+ QtXmlPatterns::tr("%1 and %2 match the start and end of a line.")
+ .arg(formatKeyword(QLatin1Char('^')))
+ .arg(formatKeyword(QLatin1Char('$')))));
+
+ retval.insert(QChar(QLatin1Char('i')),
+ PatternFlag(PatternPlatform::CaseInsensitive,
+ QtXmlPatterns::tr("Matches are case insensitive")));
+
+ retval.insert(QChar(QLatin1Char('x')),
+ PatternFlag(PatternPlatform::SimplifyWhitespace,
+ QtXmlPatterns::tr("Whitespace characters are removed, except when they appear "
+ "in character classes")));
+
+ return retval;
+}
+
+PatternPlatform::PatternPlatform(const qint8 flagsPosition) : m_compiledParts(NoPart),
+ m_flags(NoFlags),
+ m_flagsPosition(flagsPosition)
+{
+}
+
+const QRegExp PatternPlatform::pattern(const DynamicContext::Ptr &context) const
+{
+ if(m_compiledParts == FlagsAndPattern) /* This is the most common case. */
+ {
+ Q_ASSERT(m_pattern.isValid());
+ return m_pattern;
+ }
+
+ QRegExp retvalPattern;
+ Flags flags;
+
+ /* Compile the flags, if necessary. */
+ if(m_compiledParts.testFlag(FlagsPrecompiled))
+ flags = m_flags;
+ else
+ {
+ const Expression::Ptr flagsOp(m_operands.value(m_flagsPosition));
+
+ if(flagsOp)
+ flags = parseFlags(flagsOp->evaluateSingleton(context).stringValue(), context);
+ else
+ flags = NoFlags;
+ }
+
+ /* Compile the pattern, if necessary. */
+ if(m_compiledParts.testFlag(PatternPrecompiled))
+ retvalPattern = m_pattern;
+ else
+ {
+ retvalPattern = parsePattern(m_operands.at(1)->evaluateSingleton(context).stringValue(),
+ context);
+
+ }
+
+ applyFlags(flags, retvalPattern);
+
+ Q_ASSERT(m_pattern.isValid());
+ return retvalPattern;
+}
+
+void PatternPlatform::applyFlags(const Flags flags, QRegExp &patternP)
+{
+ Q_ASSERT(patternP.isValid());
+ if(flags == NoFlags)
+ return;
+
+ if(flags & CaseInsensitive)
+ {
+ patternP.setCaseSensitivity(Qt::CaseInsensitive);
+ }
+ // TODO Apply the other flags, like 'x'.
+}
+
+QRegExp PatternPlatform::parsePattern(const QString &patternP,
+ const DynamicContext::Ptr &context) const
+{
+ if(patternP == QLatin1String("(.)\\3") ||
+ patternP == QLatin1String("\\3") ||
+ patternP == QLatin1String("(.)\\2"))
+ {
+ context->error(QLatin1String("We don't want to hang infinitely on K2-MatchesFunc-9, "
+ "10 and 11. See Trolltech task 148505."),
+ ReportContext::FOER0000, this);
+ return QRegExp();
+ }
+
+ QString rewrittenPattern(patternP);
+
+ /* We rewrite some well known patterns to QRegExp style here. Note that
+ * these character classes only works in the ASCII range, and fail for
+ * others. This support needs to be in QRegExp, since it's about checking
+ * QChar::category(). */
+ rewrittenPattern.replace(QLatin1String("[\\i-[:]]"), QLatin1String("[a-zA-Z_]"));
+ rewrittenPattern.replace(QLatin1String("[\\c-[:]]"), QLatin1String("[a-zA-Z0-9_\\-\\.]"));
+ rewrittenPattern.replace(QLatin1String("\\i"), QLatin1String("[a-zA-Z:_]"));
+ rewrittenPattern.replace(QLatin1String("\\c"), QLatin1String("[a-zA-Z0-9:_\\-\\.]"));
+ rewrittenPattern.replace(QLatin1String("\\p{L}"), QLatin1String("[a-zA-Z]"));
+ rewrittenPattern.replace(QLatin1String("\\p{Lu}"), QLatin1String("[A-Z]"));
+ rewrittenPattern.replace(QLatin1String("\\p{Ll}"), QLatin1String("[a-z]"));
+ rewrittenPattern.replace(QLatin1String("\\p{Nd}"), QLatin1String("[0-9]"));
+
+ QRegExp retval(rewrittenPattern);
+
+ if(retval.isValid())
+ return retval;
+ else
+ {
+ context->error(QtXmlPatterns::tr("%1 is an invalid regular expression pattern: %2")
+ .arg(formatExpression(patternP), retval.errorString()),
+ ReportContext::FORX0002, this);
+ return QRegExp();
+ }
+}
+
+PatternPlatform::Flags PatternPlatform::parseFlags(const QString &flags,
+ const DynamicContext::Ptr &context) const
+{
+
+ if(flags.isEmpty())
+ return NoFlags;
+
+ const PatternFlag::Hash flagDescrs(flagDescriptions());
+ const int len = flags.length();
+ Flags retval = NoFlags;
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QChar flag(flags.at(i));
+ const Flag specified = flagDescrs.value(flag).flag;
+
+ if(specified != NoFlags)
+ {
+ retval |= specified;
+ continue;
+ }
+
+ /* Generate a nice error message. */
+ QString message(QtXmlPatterns::tr("%1 is an invalid flag for regular expressions. Valid flags are:")
+ .arg(formatKeyword(flag)));
+
+ /* This is formatting, so don't bother translators with it. */
+ message.append(QLatin1Char('\n'));
+
+ const PatternFlag::Hash::const_iterator end(flagDescrs.constEnd());
+ PatternFlag::Hash::const_iterator it(flagDescrs.constBegin());
+
+ for(; it != end;)
+ {
+ // TODO handle bidi correctly
+ // TODO format this with rich text(list/table)
+ message.append(formatKeyword(it.key()));
+ message.append(QLatin1String(" - "));
+ message.append(it.value().description);
+
+ ++it;
+ if(it != end)
+ message.append(QLatin1Char('\n'));
+ }
+
+ context->error(message, ReportContext::FORX0001, this);
+ return NoFlags;
+ }
+
+ return retval;
+}
+
+Expression::Ptr PatternPlatform::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(FunctionCall::compress(context));
+ if(me != this)
+ return me;
+
+ if(m_operands.at(1)->is(IDStringValue))
+ {
+ const DynamicContext::Ptr dynContext(context->dynamicContext());
+
+ m_pattern = parsePattern(m_operands.at(1)->evaluateSingleton(dynContext).stringValue(),
+ dynContext);
+ m_compiledParts |= PatternPrecompiled;
+ }
+
+ const Expression::Ptr flagOperand(m_operands.value(m_flagsPosition));
+
+ if(!flagOperand)
+ {
+ m_flags = NoFlags;
+ m_compiledParts |= FlagsPrecompiled;
+ }
+ else if(flagOperand->is(IDStringValue))
+ {
+ const DynamicContext::Ptr dynContext(context->dynamicContext());
+ m_flags = parseFlags(flagOperand->evaluateSingleton(dynContext).stringValue(),
+ dynContext);
+ m_compiledParts |= FlagsPrecompiled;
+ }
+
+ if(m_compiledParts == FlagsAndPattern)
+ applyFlags(m_flags, m_pattern);
+
+ return me;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qpatternplatform_p.h b/src/xmlpatterns/functions/qpatternplatform_p.h
new file mode 100644
index 0000000000..ce0dbd497d
--- /dev/null
+++ b/src/xmlpatterns/functions/qpatternplatform_p.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_PatternPlatform_H
+#define Patternist_PatternPlatform_H
+
+#include <QFlags>
+#include <QRegExp>
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains functionality for functions and expressions that
+ * uses regular expressions.
+ *
+ * @ingroup Patternist_utils
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class PatternPlatform : public FunctionCall
+ {
+ public:
+ /**
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#flags">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 7.6.1.1 Flags</a>
+ */
+ enum Flag
+ {
+ /**
+ * No flags are set. Default behavior is used.
+ */
+ NoFlags = 0,
+
+ /**
+ * Flag @c s
+ */
+ DotAllMode = 1,
+
+ /**
+ * Flag @c m
+ */
+ MultiLineMode = 2,
+
+ /**
+ * Flag @c i
+ */
+ CaseInsensitive = 4,
+
+ /**
+ * Flag @c x
+ */
+ SimplifyWhitespace = 8
+ };
+ typedef QFlags<Flag> Flags;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * Retrieves the pattern supplied in the arguments, taking care of compiling it,
+ * settings its flags, and everything else required for getting it ready to use. If an error
+ * occurs, an appropriate error is raised via @p context.
+ */
+ const QRegExp pattern(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns the number of captures, also called parenthesized sub-expressions, the pattern has.
+ *
+ * If the pattern isn't precompiled, -1 is returned.
+ */
+ inline int captureCount() const;
+
+ protected:
+ /**
+ * @short This constructor is protected, because this class is supposed to be sub-classed.
+ *
+ * @param flagsPosition an index position specifying the operand containing the pattern
+ * flags.
+ */
+ PatternPlatform(const qint8 flagsPosition);
+
+ private:
+ /**
+ * Enum telling whether the flags, pattern, or both
+ * have been compiled at compile time.
+ */
+ enum PreCompiledPart
+ {
+ NoPart = 0,
+ PatternPrecompiled = 1,
+ FlagsPrecompiled = 2,
+ FlagsAndPattern = PatternPrecompiled | FlagsPrecompiled
+
+ };
+ typedef QFlags<PreCompiledPart> PreCompiledParts;
+
+ Q_DISABLE_COPY(PatternPlatform)
+
+ Flags parseFlags(const QString &flags,
+ const DynamicContext::Ptr &context) const;
+
+ QRegExp parsePattern(const QString &pattern,
+ const DynamicContext::Ptr &context) const;
+
+ static void applyFlags(const Flags flags, QRegExp &pattern);
+
+ /**
+ * The parts that have been pre-compiled at compile time.
+ */
+ PreCompiledParts m_compiledParts;
+ Flags m_flags;
+ QRegExp m_pattern;
+ const qint8 m_flagsPosition;
+ };
+
+ inline int PatternPlatform::captureCount() const
+ {
+ if(m_compiledParts.testFlag(PatternPrecompiled))
+ return m_pattern.numCaptures();
+ else
+ return -1;
+ }
+
+ Q_DECLARE_OPERATORS_FOR_FLAGS(PatternPlatform::Flags)
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qqnamefns.cpp b/src/xmlpatterns/functions/qqnamefns.cpp
new file mode 100644
index 0000000000..8074db83c7
--- /dev/null
+++ b/src/xmlpatterns/functions/qqnamefns.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qpatternistlocale_p.h"
+#include "qnodenamespaceresolver_p.h"
+#include "qqnameconstructor_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+#include "qxpathhelper_p.h"
+
+#include "qqnamefns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item QNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item paramURI(m_operands.first()->evaluateSingleton(context));
+ const QString paramQName(m_operands.last()->evaluateSingleton(context).stringValue());
+
+ QString ns;
+ if(paramURI)
+ ns = paramURI.stringValue();
+
+ if(!XPathHelper::isQName(paramQName))
+ {
+ context->error(QtXmlPatterns::tr("%1 is an invalid %2").arg(formatData(paramQName),
+ formatType(context->namePool(), BuiltinTypes::xsQName)),
+ ReportContext::FOCA0002, this);
+ return Item();
+ }
+
+ QString prefix;
+ QString lname;
+ XPathHelper::splitQName(paramQName, prefix, lname);
+ const QXmlName n(context->namePool()->allocateQName(ns, lname, prefix));
+
+ if(ns.isEmpty())
+ {
+ if(prefix.isEmpty())
+ return toItem(QNameValue::fromValue(context->namePool(), n));
+ else
+ {
+ context->error(QtXmlPatterns::tr(
+ "If the first argument is the empty sequence or "
+ "a zero-length string (no namespace), a prefix "
+ "cannot be specified. Prefix %1 was specified.")
+ .arg(formatKeyword(prefix)),
+ ReportContext::FOCA0002, this);
+ return Item(); /* Silence compiler warning. */
+ }
+ }
+ else
+ return toItem(QNameValue::fromValue(context->namePool(), n));
+}
+
+Item ResolveQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item itemName(m_operands.first()->evaluateSingleton(context));
+
+ if(!itemName)
+ return Item();
+
+ const NamespaceResolver::Ptr resolver(new NodeNamespaceResolver(m_operands.last()->evaluateSingleton(context)));
+ const QString strName(itemName.stringValue());
+ const QXmlName name = QNameConstructor::expandQName<DynamicContext::Ptr,
+ ReportContext::FOCA0002,
+ ReportContext::FONS0004>(strName,
+ context,
+ resolver,
+ this);
+
+ return toItem(QNameValue::fromValue(context->namePool(), name));
+}
+
+Item PrefixFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>());
+ if(!arg)
+ return Item();
+
+ const QString prefix(context->namePool()->stringForPrefix(arg->qName().prefix()));
+
+ if(prefix.isEmpty())
+ return Item();
+ else
+ return AtomicString::fromValue(context->namePool()->stringForPrefix(arg->qName().prefix()));
+}
+
+Item LocalNameFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>());
+ return arg ? toItem(AtomicString::fromValue(context->namePool()->stringForLocalName(arg->qName().localName()))) : Item();
+}
+
+Item NamespaceURIFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>());
+ return arg ? toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(arg->qName().namespaceURI()))) : Item();
+}
+
+Item NamespaceURIForPrefixFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item prefixItem(m_operands.first()->evaluateSingleton(context));
+ QXmlName::PrefixCode prefix;
+
+ if(prefixItem)
+ prefix = context->namePool()->allocatePrefix(prefixItem.stringValue());
+ else
+ prefix = StandardPrefixes::empty;
+
+ const Item eleItem(m_operands.last()->evaluateSingleton(context));
+ Q_ASSERT(eleItem);
+
+ const QXmlName::NamespaceCode ns = eleItem.asNode().namespaceForPrefix(prefix);
+
+ if(ns == NamespaceResolver::NoBinding)
+ {
+ /* This is a bit tricky. The default namespace is not considered an in-scope binding
+ * on a node, but the specification for this function do consider it a binding and therefore
+ * the empty string. */
+ if(prefix == StandardPrefixes::empty)
+ return CommonValues::EmptyString;
+ else
+ return Item();
+ }
+ else
+ return toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(ns)));
+}
+
+Item::Iterator::Ptr InScopePrefixesFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item e(m_operands.first()->evaluateSingleton(context));
+
+ const QVector<QXmlName> nbs(e.asNode().namespaceBindings());
+ const int len = nbs.size();
+ const NamePool::Ptr np(context->namePool());
+
+ QList<Item> result;
+
+ for(int i = 0; i < len; ++i)
+ result.append(AtomicString::fromValue(np->stringForPrefix(nbs.at(i).prefix())));
+
+ return makeListIterator(result);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qqnamefns_p.h b/src/xmlpatterns/functions/qqnamefns_p.h
new file mode 100644
index 0000000000..6d22d063e5
--- /dev/null
+++ b/src/xmlpatterns/functions/qqnamefns_p.h
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_QNameFNs_H
+#define Patternist_QNameFNs_H
+
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#QName-funcs">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 11 Functions Related to QNames</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:QXmlName()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class QNameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:resolve-QXmlName()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ResolveQNameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:prefix-from-QXmlName()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class PrefixFromQNameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:local-name-from-QXmlName()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class LocalNameFromQNameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:local-name-from-QXmlName()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NamespaceURIFromQNameFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:namespace-uri-from-QXmlName()</tt>.
+ *
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class NamespaceURIForPrefixFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:in-scope-prefixes()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class InScopePrefixesFN : public FunctionCall
+ {
+ public:
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qresolveurifn.cpp b/src/xmlpatterns/functions/qresolveurifn.cpp
new file mode 100644
index 0000000000..6068e8fbf0
--- /dev/null
+++ b/src/xmlpatterns/functions/qresolveurifn.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qanyuri_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qatomicstring_p.h"
+
+#include "qresolveurifn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ResolveURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item relItem(m_operands.first()->evaluateSingleton(context));
+
+ if(relItem)
+ {
+ const QString base(m_operands.last()->evaluateSingleton(context).stringValue());
+ const QString relative(relItem.stringValue());
+
+ const QUrl baseURI(AnyURI::toQUrl<ReportContext::FORG0002, DynamicContext::Ptr>(base, context, this));
+ const QUrl relativeURI(AnyURI::toQUrl<ReportContext::FORG0002, DynamicContext::Ptr>(relative, context, this));
+
+ return toItem(AnyURI::fromValue(baseURI.resolved(relativeURI)));
+ }
+ else
+ return Item();
+}
+
+Expression::Ptr ResolveURIFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2);
+
+ if(m_operands.count() == 1)
+ {
+ /* Our base URI is always well-defined. */
+ m_operands.append(wrapLiteral(toItem(AnyURI::fromValue(context->baseURI())), context, this));
+ }
+
+ return FunctionCall::typeCheck(context, reqType);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qresolveurifn_p.h b/src/xmlpatterns/functions/qresolveurifn_p.h
new file mode 100644
index 0000000000..d49007a45e
--- /dev/null
+++ b/src/xmlpatterns/functions/qresolveurifn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ResolveURIFN_H
+#define Patternist_ResolveURIFN_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:resolve-uri()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ResolveURIFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qsequencefns.cpp b/src/xmlpatterns/functions/qsequencefns.cpp
new file mode 100644
index 0000000000..f6d5391e5b
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencefns.cpp
@@ -0,0 +1,353 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qdistinctiterator_p.h"
+#include "qebvextractor_p.h"
+#include "qemptysequence_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qindexofiterator_p.h"
+#include "qinsertioniterator_p.h"
+#include "qinteger_p.h"
+#include "qremovaliterator_p.h"
+#include "qsequencegeneratingfns_p.h"
+#include "qsubsequenceiterator_p.h"
+
+#include "qsequencefns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool BooleanFN::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operands.first()->evaluateEBV(context);
+}
+
+Expression::Ptr BooleanFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ return EBVExtractor::typeCheck<FunctionCall>(context, reqType, this);
+}
+
+Item::Iterator::Ptr IndexOfFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return Item::Iterator::Ptr(new IndexOfIterator(m_operands.first()->evaluateSequence(context),
+ m_operands.at(1)->evaluateSingleton(context),
+ comparator(), context,
+ ConstPtr(this)));
+}
+
+Expression::Ptr IndexOfFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+ const ItemType::Ptr t1(m_operands.first()->staticType()->itemType());
+ const ItemType::Ptr t2(m_operands.at(1)->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ return EmptySequence::create(this, context);
+ }
+ else
+ {
+ prepareComparison(fetchComparator(t1, t2, context));
+ return me;
+ }
+}
+
+Item::Iterator::Ptr DistinctValuesFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return Item::Iterator::Ptr(new DistinctIterator(m_operands.first()->evaluateSequence(context),
+ comparator(),
+ ConstPtr(this),
+ context));
+}
+
+Expression::Ptr DistinctValuesFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
+ const ItemType::Ptr t1(m_operands.first()->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1)
+ return EmptySequence::create(this, context);
+ else if(!m_operands.first()->staticType()->cardinality().allowsMany())
+ return m_operands.first();
+ else if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1))
+ return me;
+ else
+ {
+ prepareComparison(fetchComparator(t1, t1, context));
+ return me;
+ }
+}
+
+SequenceType::Ptr DistinctValuesFN::staticType() const
+{
+ const SequenceType::Ptr t(m_operands.first()->staticType());
+ return makeGenericSequenceType(t->itemType(),
+ t->cardinality().allowsMany() ? Cardinality::oneOrMore()
+ : Cardinality::exactlyOne());
+}
+
+Item::Iterator::Ptr InsertBeforeFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr target(m_operands.first()->evaluateSequence(context));
+ const Item::Iterator::Ptr inserts(m_operands.at(2)->evaluateSequence(context));
+
+ xsInteger position = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger();
+
+ if(position < 1)
+ position = 1;
+
+ return Item::Iterator::Ptr(new InsertionIterator(target, position, inserts));
+}
+
+Item InsertBeforeFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return evaluateSequence(context)->next();
+}
+
+SequenceType::Ptr InsertBeforeFN::staticType() const
+{
+ const SequenceType::Ptr t1(m_operands.first()->staticType());
+ const SequenceType::Ptr t2(m_operands.last()->staticType());
+
+ return makeGenericSequenceType(t1->itemType() | t2->itemType(),
+ t1->cardinality() + t2->cardinality());
+}
+
+Item::Iterator::Ptr RemoveFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
+ Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));
+
+ if(pos < 1)
+ return it;
+
+ return Item::Iterator::Ptr(new RemovalIterator(it, pos));
+}
+
+Item RemoveFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
+ if(pos <= 1)
+ return Item();
+
+ return m_operands.first()->evaluateSingleton(context);
+}
+
+SequenceType::Ptr RemoveFN::staticType() const
+{
+ const SequenceType::Ptr opType(m_operands.first()->staticType());
+ const Cardinality c(opType->cardinality());
+
+ if(c.minimum() == 0)
+ return makeGenericSequenceType(opType->itemType(), c);
+ else
+ {
+ return makeGenericSequenceType(opType->itemType(),
+ Cardinality::fromRange(c.minimum() - 1,
+ c.maximum()));
+ }
+}
+
+Item::Iterator::Ptr ReverseFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_operands.first()->evaluateSequence(context)->toReversed();
+}
+
+Expression::Ptr ReverseFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(m_operands.first()->staticType()->cardinality().allowsMany())
+ return FunctionCall::typeCheck(context, reqType);
+ else
+ return m_operands.first()->typeCheck(context, reqType);
+}
+
+SequenceType::Ptr ReverseFN::staticType() const
+{
+ return m_operands.first()->staticType();
+}
+
+SubsequenceFN::SubsequenceFN() : m_hasTypeChecked(false)
+{
+}
+
+Expression::Ptr SubsequenceFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_hasTypeChecked = true;
+ return FunctionCall::typeCheck(context, reqType);
+}
+
+Item::Iterator::Ptr SubsequenceFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));
+
+ xsInteger startingLoc = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->round()->toInteger();
+ xsInteger length = -1;
+
+ if(m_operands.count() == 3)
+ {
+ length = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
+
+ if(startingLoc + length < 1 || (startingLoc > (startingLoc + length)))
+ return CommonValues::emptyIterator;
+ }
+
+ /* F&O, 15.1.10, "If $startingLoc is zero or negative, the
+ * subsequence includes items from the beginning of the $sourceSeq." */
+ if(startingLoc < 1)
+ startingLoc = 1;
+
+ if(length < 1 && length != -1)
+ return CommonValues::emptyIterator;
+ else
+ return Item::Iterator::Ptr(new SubsequenceIterator(it, startingLoc, length));
+}
+
+Item SubsequenceFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return evaluateSequence(context)->next();
+}
+
+Expression::Ptr SubsequenceFN::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(FunctionCall::compress(context));
+ if(me != this)
+ return me;
+
+ const Expression::Ptr lenArg(m_operands.value(2));
+ if(lenArg && lenArg->isEvaluated())
+ {
+ const xsInteger length = lenArg->as<Literal>()->item().as<Numeric>()->round()->toInteger();
+
+ if(length <= 0)
+ return EmptySequence::create(this, context);
+ }
+
+ return me;
+}
+
+SequenceType::Ptr SubsequenceFN::staticType() const
+{
+ const SequenceType::Ptr opType(m_operands.first()->staticType());
+ const Cardinality opCard(opType->cardinality());
+
+ /* Optimization: we can do much stronger inference here. If the length is a
+ * constant, we can constrain the range at least upwards of the
+ * cardinality, for instance. */
+
+ /* The subsequence(expr, 1, 1), add empty-sequence() to the static type.
+ *
+ * Note that we cannot do all these inferences before we've typechecked our
+ * operands. The only known case of where our staticType() is called before
+ * typeCheck() is through xmlpatternsview, although it wouldn't be
+ * surprising if the more exotic paths can achieve that too.
+ */
+ if(m_hasTypeChecked &&
+ m_operands.at(1)->isEvaluated() &&
+ m_operands.count() == 3 &&
+ m_operands.at(2)->isEvaluated() &&
+ m_operands.at(1)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1 &&
+ m_operands.at(2)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1)
+ {
+ return makeGenericSequenceType(opType->itemType(),
+ opCard.toWithoutMany());
+ }
+ else
+ {
+ return makeGenericSequenceType(opType->itemType(),
+ opCard | Cardinality::zeroOrOne());
+ }
+}
+
+Expression::Ptr DocFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* See the doxygen documentation for this function for the explanation
+ * to why this implementation is here, as opposed to in
+ * qsequencegeneratingfns.cpp. */
+
+ Q_ASSERT(context);
+
+ prepareStaticBaseURI(context);
+
+ const Expression::Ptr uriOp(m_operands.first());
+
+ if(!uriOp->isEvaluated())
+ return Expression::Ptr(FunctionCall::typeCheck(context, reqType));
+
+ const Item uriItem(uriOp->evaluateSingleton(context->dynamicContext()));
+
+ if(!uriItem)
+ return EmptySequence::create(this, context)->typeCheck(context, reqType); // TODO test this
+
+ /* These two lines were previously in a separate function but are now duplicated
+ * in DocFN::evaluateSingleton(), as part of a workaround for solaris-cc-64. */
+ const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(uriItem.stringValue(), context, this));
+ const QUrl uri(context->resolveURI(mayRela, staticBaseURI()));
+
+ /* The URI is supplied statically, so, let's try to be clever. */
+ Q_ASSERT_X(context->resourceLoader(), Q_FUNC_INFO,
+ "No resource loader is set in the StaticContext.");
+ m_type = context->resourceLoader()->announceDocument(uri, ResourceLoader::MayUse);
+
+ if(m_type)
+ {
+ Q_ASSERT(CommonSequenceTypes::ZeroOrOneDocumentNode->matches(m_type));
+ return Expression::Ptr(FunctionCall::typeCheck(context, reqType));
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("It will not be possible to retrieve %1.").arg(formatURI(uri)),
+ ReportContext::FODC0002, this);
+ return Expression::Ptr();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qsequencefns_p.h b/src/xmlpatterns/functions/qsequencefns_p.h
new file mode 100644
index 0000000000..3f79a5f55e
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencefns_p.h
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SequenceFNs_H
+#define Patternist_SequenceFNs_H
+
+#include "qatomiccomparator_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qliteral_p.h"
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#general-seq-funcs">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 15.1 General Functions and Operators on Sequences</a>.
+ *
+ * @todo document that some functions have both eval funcs implented.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:boolean()</tt>.
+ *
+ * @see EBVExtractor
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class BooleanFN : public FunctionCall
+ {
+ public:
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ /**
+ * If @p reqType is CommonSequenceTypes::EBV, the type check of
+ * the operand is returned. Hence, this removes redundant calls
+ * to <tt>fn:boolean()</tt>.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ };
+
+ /**
+ * @short Implements the function <tt>fn:index-of()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class IndexOfFN : public FunctionCall,
+ public ComparisonPlatform<IndexOfFN, false>
+ {
+ public:
+ inline IndexOfFN() : ComparisonPlatform<IndexOfFN, false>()
+ {
+ }
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return AtomicComparator::OperatorEqual;
+ }
+ };
+
+ /**
+ * @short Implements the functions <tt>fn:exists()</tt> and <tt>fn:empty()</tt>.
+ *
+ * Existence is a template value class. Appropriate implementations are achieved
+ * by instantiating it with either IDExistsFN or IDEmptyFN.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ template<const Expression::ID Id>
+ class Existence : public FunctionCall
+ {
+ public:
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const
+ {
+ if(Id == IDExistsFN)
+ return !m_operands.first()->evaluateSequence(context)->isEmpty();
+ else
+ return m_operands.first()->evaluateSequence(context)->isEmpty();
+ }
+
+ /**
+ * Attempts to rewrite to @c false or @c true by looking at the static
+ * cardinality of its operand.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context)
+ {
+ Q_ASSERT(Id == IDExistsFN || Id == IDEmptyFN);
+ const Expression::Ptr me(FunctionCall::compress(context));
+
+ if(me != this)
+ return me;
+
+ const Cardinality myCard((Id == IDExistsFN) ? Cardinality::oneOrMore() : Cardinality::empty());
+
+ const Cardinality card(m_operands.first()->staticType()->cardinality());
+ if(myCard.isMatch(card))
+ { /* Since the dynamic type always is narrower than the static type or equal, and that the
+ static type is in scope, it means we will always be true. */
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ }
+ else
+ {
+ /* Is it even possible to hit? */
+ if(myCard.canMatch(card))
+ {
+ return me;
+ }
+ else
+ { /* We can never hit. */
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ }
+ }
+ }
+ };
+
+ /**
+ * @short Implements the function <tt>fn:distinct-values()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DistinctValuesFN : public FunctionCall,
+ public ComparisonPlatform<IndexOfFN, false>
+ {
+ public:
+ inline DistinctValuesFN() : ComparisonPlatform<IndexOfFN, false>()
+ {
+ }
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ /**
+ * Performs necessary type checks, but also implements the optimization
+ * of rewriting to its operand if the operand's cardinality is zero-or-one
+ * or exactly-one.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ /**
+ * @returns a type whose item type is the type of the first operand, and
+ * a cardinality which is non-empty if the first operand's type is non-empty
+ * and allows exactly-one. The latter is needed for operands which has the
+ * cardinality 2+, since distinct-values possibly removes items from the
+ * source sequence.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ protected:
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return AtomicComparator::OperatorEqual;
+ }
+ };
+
+ /**
+ * @short Implements the function <tt>fn:insert-before()</tt>.
+ *
+ * @todo docs, explain why evaluateSequence and evaluateSingleton is implemented
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class InsertBeforeFN : public FunctionCall
+ {
+ public:
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Implements the static enferences rules. The function's static item type
+ * is the union type of the first and third argument, and the cardinality is
+ * the cardinalities of the two operands added together. For example,
+ * insert-before((1, "str"), 1, xs:double(0)) has the static type xs:anyAtomicType+.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_insert_before">XQuery 1.0
+ * and XPath 2.0 Formal Semantics, 7.2.15 The fn:insert-before function</a>
+ */
+ virtual SequenceType::Ptr staticType() const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:remove()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class RemoveFN : public FunctionCall
+ {
+ public:
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Implements the static enferences rules, "Since one item may be removed
+ * from the sequence, the resulting type is made optional:"
+ *
+ * <tt>statEnv |- (FN-URI,"remove")(Type, Type1) : prime(Type) * quantifier(Type)?</tt>
+ *
+ * However, because Patternist's type system is more fine grained than Formal Semantics,
+ * the sequence isn't made optional. Instead its minimum length is reduced with one.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_remove">XQuery 1.0
+ * and XPath 2.0 Formal Semantics, 7.2.11 The fn:remove function</a>
+ */
+ virtual SequenceType::Ptr staticType() const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:reverse()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ReverseFN : public FunctionCall
+ {
+ public:
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * Formally speaking, the type inference is:
+ *
+@verbatim
+statEnv |- (FN-URI,"reverse")(Type) : prime(Type) * quantifier(Type)
+@endverbatim
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_reverse">XQuery 1.0
+ * and XPath 2.0 Formal Semantics, 7.2.12 The fn:reverse function</a>
+ * @returns the static type of the function's first argument.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:subsequence()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @todo Type inference can be made stronger for this function
+ */
+ class SubsequenceFN : public FunctionCall
+ {
+ public:
+ SubsequenceFN();
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * This function implements rewrites the SubsequenceFN instance into an
+ * empty sequence if its third argument, the sequence length argument, is
+ * evaluated and is effectively equal or less than zero.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * Partially implements the static type inference rules.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_subsequence">XQuery 1.0
+ * and XPath 2.0 Formal Semantics, 7.2.13 The fn:subsequence function</a>
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ private:
+ bool m_hasTypeChecked;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qsequencegeneratingfns.cpp b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp
new file mode 100644
index 0000000000..c77a3e76e2
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStack>
+#include <QStringList>
+
+#include "qanyuri_p.h"
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qemptysequence_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qnodesort_p.h"
+#include "qpatternistlocale_p.h"
+#include "private/qxmlutils_p.h"
+
+#include "qsequencegeneratingfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+IdFN::IdFN() : m_hasCreatedSorter(false)
+{
+}
+
+Item IdFN::mapToItem(const QString &id,
+ const IDContext &context) const
+{
+ return context.second->elementById(context.first->namePool()->allocateQName(QString(), id));
+}
+
+/**
+ * @short Helper class for StringSplitter
+ *
+ * Needed by the QAbstractXmlForwardIterator sub-class.
+ *
+ * @relates StringSplitter
+ */
+template<>
+bool qIsForwardIteratorEnd(const QString &unit)
+{
+ return unit.isNull();
+}
+
+/**
+ * @short Helper class for IdFN.
+ *
+ * StringSplitter takes an Iterator which delivers strings of this kind:
+ *
+ * "a", "b c", "%invalidNCName", " ", "d"
+ *
+ * and we deliver instead:
+ *
+ * "a", "b", "c", "d"
+ *
+ * That is, we:
+ * - Remove invalid @c NCName
+ * - Split IDREFs into individual NCNames
+ *
+ * @author Frans Englich
+ */
+class StringSplitter : public QAbstractXmlForwardIterator<QString>
+{
+public:
+ StringSplitter(const Item::Iterator::Ptr &source);
+ virtual QString next();
+ virtual QString current() const;
+ virtual qint64 position() const;
+private:
+ QString loadNext();
+ const Item::Iterator::Ptr m_source;
+ QStack<QString> m_buffer;
+ QString m_current;
+ qint64 m_position;
+ bool m_sourceAtEnd;
+};
+
+StringSplitter::StringSplitter(const Item::Iterator::Ptr &source) : m_source(source)
+ , m_position(0)
+ , m_sourceAtEnd(false)
+{
+ Q_ASSERT(m_source);
+ m_buffer.push(loadNext());
+}
+
+QString StringSplitter::next()
+{
+ /* We also check m_position, we want to load on our first run. */
+ if(!m_buffer.isEmpty())
+ {
+ ++m_position;
+ m_current = m_buffer.pop();
+ return m_current;
+ }
+ else if(m_sourceAtEnd)
+ {
+ m_current.clear();
+ m_position = -1;
+ return QString();
+ }
+
+ return loadNext();
+}
+
+QString StringSplitter::loadNext()
+{
+ const Item sourceNext(m_source->next());
+
+ if(sourceNext.isNull())
+ {
+ m_sourceAtEnd = true;
+ /* We might have strings in m_buffer, let's empty it. */
+ return next();
+ }
+
+ const QStringList candidates(sourceNext.stringValue().simplified().split(QLatin1Char(' ')));
+ const int count = candidates.length();
+
+ for(int i = 0; i < count; ++i)
+ {
+ const QString &at = candidates.at(i);
+
+ if(QXmlUtils::isNCName(at))
+ m_buffer.push(at);
+ }
+
+ /* So, now we have populated m_buffer, let's start from the beginning. */
+ return next();
+}
+
+QString StringSplitter::current() const
+{
+ return m_current;
+}
+
+qint64 StringSplitter::position() const
+{
+ return m_position;
+}
+
+Item::Iterator::Ptr IdFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr idrefs(m_operands.first()->evaluateSequence(context));
+ const Item node(m_operands.last()->evaluateSingleton(context));
+
+ checkTargetNode(node.asNode(), context, ReportContext::FODC0001);
+
+ return makeItemMappingIterator<Item,
+ QString,
+ IdFN::ConstPtr,
+ IDContext>(ConstPtr(this),
+ StringSplitter::Ptr(new StringSplitter(idrefs)),
+ qMakePair(context, node.asNode().model()));
+}
+
+Expression::Ptr IdFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(m_hasCreatedSorter)
+ return FunctionCall::typeCheck(context, reqType);
+ else
+ {
+ const Expression::Ptr newMe(new NodeSortExpression(Expression::Ptr(this)));
+ context->wrapExpressionWith(this, newMe);
+ m_hasCreatedSorter = true;
+ return newMe->typeCheck(context, reqType);
+ }
+}
+
+Item::Iterator::Ptr IdrefFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr ids(m_operands.first()->evaluateSequence(context));
+
+ Item mId(ids->next());
+ if(!mId)
+ return CommonValues::emptyIterator;
+
+ const Item node(m_operands.last()->evaluateSingleton(context));
+ checkTargetNode(node.asNode(), context, ReportContext::FODC0001);
+
+ return CommonValues::emptyIterator; /* TODO Haven't implemented further. */
+}
+
+Item DocFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item itemURI(m_operands.first()->evaluateSingleton(context));
+
+ if(!itemURI)
+ return Item();
+
+ /* These two lines were previously in a separate function but are now duplicated
+ * in DocAvailableFN::evaluateEBV() and DocFN::typeCheck(),
+ * as part of a workaround for solaris-cc-64. DocFN::typeCheck() is in qsequencefns.cpp
+ * as part of that workaround. */
+ const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(itemURI.stringValue(), context, this));
+ const QUrl uri(context->resolveURI(mayRela, staticBaseURI()));
+
+ Q_ASSERT(uri.isValid());
+ Q_ASSERT(!uri.isRelative());
+
+ const Item doc(context->resourceLoader()->openDocument(uri, context));
+
+ return doc;
+}
+
+SequenceType::Ptr DocFN::staticType() const
+{
+ if(m_type)
+ return m_type;
+ else
+ return CommonSequenceTypes::ZeroOrOneDocumentNode;
+}
+
+bool DocAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item itemURI(m_operands.first()->evaluateSingleton(context));
+
+ /* 15.5.4 fn:doc reads: "If $uri is the empty sequence, the result is an empty sequence."
+ * Hence, we return false for the empty sequence, because this doesn't hold true:
+ * "If this function returns true, then calling fn:doc($uri) within
+ * the same execution scope must return a document node."(15.5.5 fn:doc-available) */
+ if(!itemURI)
+ return false;
+
+ /* These two lines are duplicated in DocFN::evaluateSingleton(), as part
+ * of a workaround for solaris-cc-64. */
+ const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(itemURI.stringValue(), context, this));
+ const QUrl uri(context->resolveURI(mayRela, staticBaseURI()));
+
+ Q_ASSERT(!uri.isRelative());
+ return context->resourceLoader()->isDocumentAvailable(uri);
+}
+
+Item::Iterator::Ptr CollectionFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ // TODO resolve with URI resolve
+ if(m_operands.isEmpty())
+ {
+ // TODO check default collection
+ context->error(QtXmlPatterns::tr("The default collection is undefined"),
+ ReportContext::FODC0002, this);
+ return CommonValues::emptyIterator;
+ }
+ else
+ {
+ const Item itemURI(m_operands.first()->evaluateSingleton(context));
+
+ if(itemURI)
+ {
+ const QUrl uri(AnyURI::toQUrl<ReportContext::FODC0004>(itemURI.stringValue(), context, this));
+
+ // TODO 2. Resolve against static context base URI(store base URI at compile time)
+ context->error(QtXmlPatterns::tr("%1 cannot be retrieved").arg(formatResourcePath(uri)),
+ ReportContext::FODC0004, this);
+ return CommonValues::emptyIterator;
+ }
+ else
+ {
+ /* This is out default collection currently, */
+ return CommonValues::emptyIterator;
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qsequencegeneratingfns_p.h b/src/xmlpatterns/functions/qsequencegeneratingfns_p.h
new file mode 100644
index 0000000000..881a4d9ed3
--- /dev/null
+++ b/src/xmlpatterns/functions/qsequencegeneratingfns_p.h
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SequenceGeneratingFNs_H
+#define Patternist_SequenceGeneratingFNs_H
+
+#include "qanyuri_p.h"
+#include "qcontextnodechecker_p.h"
+#include "qstaticbaseuricontainer_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#fns-that-generate-sequences">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 15.5 Functions and Operators that Generate Sequences</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:id()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class IdFN : public ContextNodeChecker
+ {
+ public:
+ IdFN();
+ typedef QPair<DynamicContext::Ptr, const QAbstractXmlNodeModel *> IDContext;
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ inline Item mapToItem(const QString &id,
+ const IDContext &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ private:
+ typedef QExplicitlySharedDataPointer<const IdFN> ConstPtr;
+ bool m_hasCreatedSorter;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:idref()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class IdrefFN : public ContextNodeChecker
+ {
+ public:
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:doc()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DocFN : public StaticBaseUriContainer
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * The implementation of this function is placed in a different compilation unit,
+ * namely qsequencefns.cpp, to workaround a compiler bug on
+ * solaris-cc-64, suspected to be related to the instantiation of QUrl::toQUrl().
+ *
+ * @see <a
+ * href="http://onesearch.sun.com/search/onesearch/index.jsp?qt=6532605&site=sunsolve&otf=ss&col=support-sunsolve&otf=sunsolve&site=ss&col=search-sunsolve">Sun,
+ * multiply-defined label for template instance, bug 6532605</a>
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+
+ private:
+ SequenceType::Ptr m_type;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:doc-available()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DocAvailableFN : public StaticBaseUriContainer
+ {
+ public:
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:collection()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class CollectionFN : public FunctionCall
+ {
+ public:
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qstaticbaseuricontainer_p.h b/src/xmlpatterns/functions/qstaticbaseuricontainer_p.h
new file mode 100644
index 0000000000..ab21f24be4
--- /dev/null
+++ b/src/xmlpatterns/functions/qstaticbaseuricontainer_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_StaticBaseUriContainer_H
+#define Patternist_StaticBaseUriContainer_H
+
+#include <QUrl>
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for functions that needs to
+ * store the static base URI for use at runtime.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class StaticBaseUriContainer : public FunctionCall
+ {
+ protected:
+ inline StaticBaseUriContainer()
+ {
+ }
+
+ inline void prepareStaticBaseURI(const StaticContext::Ptr &context)
+ {
+ m_staticBaseURI = context->baseURI();
+ }
+
+ inline const QUrl &staticBaseURI() const
+ {
+ return m_staticBaseURI;
+ }
+
+ /**
+ * Calls prepareStaticBaseURI(), and return the return value of
+ * FunctionCall::typeCheck(), forwarding the arguments.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+ {
+ prepareStaticBaseURI(context);
+ return FunctionCall::typeCheck(context, reqType);
+ }
+
+ private:
+ Q_DISABLE_COPY(StaticBaseUriContainer)
+ QUrl m_staticBaseURI;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+#endif
diff --git a/src/xmlpatterns/functions/qstaticnamespacescontainer.cpp b/src/xmlpatterns/functions/qstaticnamespacescontainer.cpp
new file mode 100644
index 0000000000..d3dcf99acb
--- /dev/null
+++ b/src/xmlpatterns/functions/qstaticnamespacescontainer.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstaticnamespacescontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr StaticNamespacesContainer::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_resolver = NamespaceResolver::Ptr(context->namespaceBindings());
+ Q_ASSERT(m_resolver);
+
+ return FunctionCall::typeCheck(context, reqType);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qstaticnamespacescontainer_p.h b/src/xmlpatterns/functions/qstaticnamespacescontainer_p.h
new file mode 100644
index 0000000000..3d21e151fc
--- /dev/null
+++ b/src/xmlpatterns/functions/qstaticnamespacescontainer_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_StaticNamespacesContainer_H
+#define Patternist_StaticNamespacesContainer_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper subclass that stores a NamespaceResolver for the static
+ * namespaces.
+ *
+ * This is used by functionality which needs to resolve names against the
+ * statically known namespaces, at runtime. A good example of this is @c
+ * function-available().
+ *
+ * The resolver is accessed through staticNamespaces(), which will be
+ * available after the typeCheck() stage.
+ *
+ * This class must be subclassed.
+ *
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class StaticNamespacesContainer : public FunctionCall
+ {
+ public:
+ /**
+ * Reimplemented to store data from the @p context.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ protected:
+ /**
+ * Before typeCheck(), behavior of this function is undefined. After
+ * typeCheck(), this function guarantees to return a valid pointer.
+ */
+ inline const NamespaceResolver::Ptr &staticNamespaces() const
+ {
+ Q_ASSERT(m_resolver);
+ return m_resolver;
+ }
+
+ /**
+ * This constructor only exists to ensure this class is subclassed.
+ */
+ inline StaticNamespacesContainer()
+ {
+ }
+
+ private:
+ NamespaceResolver::Ptr m_resolver;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qstringvaluefns.cpp b/src/xmlpatterns/functions/qstringvaluefns.cpp
new file mode 100644
index 0000000000..d57dd4c0b1
--- /dev/null
+++ b/src/xmlpatterns/functions/qstringvaluefns.cpp
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloat_p.h"
+#include "qatomicstring_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qinteger_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qschemanumeric_p.h"
+
+#include "qstringvaluefns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ConcatFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List::const_iterator it(m_operands.constBegin());
+ QString result;
+
+ for(; it != end; ++it)
+ {
+ Item item((*it)->evaluateSingleton(context));
+
+ if(item)
+ result += item.stringValue();
+ }
+
+ return AtomicString::fromValue(result);
+}
+
+Item StringJoinFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Item::Iterator::Ptr it(m_operands.first()->evaluateSequence(context));
+ Q_ASSERT(it);
+ Item current(it->next());
+
+ if(!current) /* Exit early, don't evaluate the separator. */
+ return CommonValues::EmptyString;
+
+ QString result;
+ QString separator;
+ const Item isep(m_operands.at(1)->evaluateSingleton(context));
+
+ if(isep)
+ separator = isep.stringValue();
+
+ while(true)
+ {
+ result += current.stringValue();
+ current = it->next();
+
+ if(!current)
+ break;
+
+ result += separator;
+ }
+
+ return result.isEmpty()
+ ? toItem(CommonValues::EmptyString)
+ : toItem(AtomicString::fromValue(result));
+}
+
+Expression::Ptr StringJoinFN::compress(const StaticContext::Ptr &context)
+{
+ if(m_operands.first()->staticType()->cardinality().allowsMany())
+ return FunctionCall::compress(context);
+ else
+ {
+ if(m_operands.first()->is(IDEmptySequence))
+ return wrapLiteral(CommonValues::EmptyString, context, this);
+ else
+ return m_operands.first()->compress(context);
+ }
+}
+
+Item SubstringFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(!item)
+ return CommonValues::EmptyString;
+
+ const QString str(item.stringValue());
+
+ const xsDouble dblStart = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()
+ ->round()->toDouble();
+ if(qIsNaN(dblStart))
+ return CommonValues::EmptyString;
+
+ /* XPath starts from 1, but C++ starts from 0. */
+ xsInteger startingLoc = Double::fromValue(dblStart)->round()->toInteger() - 1;
+
+ xsInteger length = 0;
+ if(m_operands.count() == 2)
+ length = str.length() - startingLoc;
+ else
+ {
+ const xsDouble dblLen = m_operands.at(2)->evaluateSingleton(context).as<Numeric>()
+ ->round()->toDouble();
+
+ if(qIsNaN(dblLen))
+ return CommonValues::EmptyString;
+
+ length = Double::fromValue(dblLen)->round()->toInteger();
+ if(startingLoc > startingLoc + length)
+ return CommonValues::EmptyString;
+ }
+
+ if(startingLoc < 0)
+ {
+ length = length + startingLoc;
+ startingLoc = 0;
+ }
+
+ return AtomicString::fromValue(str.mid(startingLoc, length));
+}
+
+Item StringLengthFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ /* fn:string() is re-implemented "inline" here. */
+ if(item)
+ return Integer::fromValue(item.stringValue().length());
+ else
+ return CommonValues::IntegerZero;
+}
+
+NormalizeUnicodeFN::NormalizeUnicodeFN() : m_normForm(QString::NormalizationForm_C)
+{
+}
+
+Item NormalizeSpaceFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+
+ if(!arg)
+ return CommonValues::EmptyString;
+
+ return toItem(AtomicString::fromValue(arg.stringValue().simplified()));
+}
+
+Item NormalizeUnicodeFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+
+ if(!arg)
+ return CommonValues::EmptyString;
+
+ int normForm;
+
+ /* The second argument has been removed, if we've already determined the form. */
+ if(m_operands.count() == 1)
+ normForm = m_normForm;
+ else
+ {
+ normForm = determineNormalizationForm(context);
+ if(normForm == -1)
+ return toItem(AtomicString::fromValue(arg.stringValue()));
+ }
+
+ return AtomicString::fromValue(arg.stringValue().normalized(
+ static_cast<QString::NormalizationForm>(normForm)));
+}
+
+Expression::Ptr NormalizeUnicodeFN::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(FunctionCall::compress(context));
+ if(me != this)
+ return me;
+
+ Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2);
+
+ if(m_operands.count() == 1)
+ m_normForm = QString::NormalizationForm_C;
+ else if(m_operands.last()->is(IDStringValue))
+ {
+ m_normForm = static_cast<QString::NormalizationForm>(
+ determineNormalizationForm(context->dynamicContext()));
+
+ if(m_normForm == -1)
+ return m_operands.first();
+
+ /* Remove the operand since we don't need it anymore. */
+ m_operands.removeLast();
+ }
+
+ return me;
+}
+
+int NormalizeUnicodeFN::determineNormalizationForm(const DynamicContext::Ptr &context) const
+{
+ const QString strRepr(m_operands.last()->evaluateSingleton(context).stringValue().trimmed().toUpper());
+
+ /* TODO. Put these values in a QHash for faster lookup. Keep thread safety in mind. */
+ if(strRepr.isEmpty())
+ return -1;
+ else if(strRepr == QLatin1String("NFC"))
+ return QString::NormalizationForm_C;
+ else if(strRepr == QLatin1String("NFD"))
+ return QString::NormalizationForm_D;
+ else if(strRepr == QLatin1String("NFKC"))
+ return QString::NormalizationForm_KC;
+ else if(strRepr == QLatin1String("NFKD"))
+ return QString::NormalizationForm_KD;
+ else
+ {
+ /* What form is FULLY_NORMALIZED? Is a code path available for that somewhere? */
+ context->error(QtXmlPatterns::tr("The normalization form %1 is "
+ "unsupported. The supported forms are "
+ "%2, %3, %4, and %5, and none, i.e. "
+ "the empty string (no normalization).")
+ .arg(formatKeyword(strRepr))
+ .arg(formatKeyword("NFC"))
+ .arg(formatKeyword("NFD"))
+ .arg(formatKeyword("NFKC"))
+ .arg(formatKeyword("NFKD")),
+ ReportContext::FOCH0003,
+ this);
+ return QString::NormalizationForm_C; /* Silence compiler warning. */
+ }
+}
+
+Item UpperCaseFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(!item)
+ return CommonValues::EmptyString;
+
+ return AtomicString::fromValue(item.stringValue().toUpper());
+}
+
+Item LowerCaseFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(!item)
+ return CommonValues::EmptyString;
+
+ return AtomicString::fromValue(item.stringValue().toLower());
+}
+
+Item TranslateFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(!item)
+ return CommonValues::EmptyString;
+
+ const QString mapString(m_operands.at(1)->evaluateSingleton(context).stringValue());
+ const QString arg(item.stringValue());
+
+ if(mapString.isEmpty())
+ return AtomicString::fromValue(arg);
+
+ const QString transString(m_operands.at(2)->evaluateSingleton(context).stringValue());
+ const int transLen = transString.length();
+ const int argLen = arg.length();
+
+ QString result;
+ result.reserve(argLen);
+ int outI = 0;
+
+ for(int i = 0; i < argLen; ++i)
+ {
+ const QChar argCh(arg.at(i));
+ const int mapPos = mapString.indexOf(argCh);
+
+ if(mapPos == -1)
+ {
+ result[outI] = argCh;
+ ++outI;
+ continue;
+ }
+ else if(mapPos >= transLen)
+ continue;
+
+ const QChar transCh(transString.at(mapPos));
+
+ if(transCh.isNull())
+ continue;
+
+ result[outI] = transCh;
+ ++outI;
+ }
+
+ result.truncate(outI);
+ return AtomicString::fromValue(result);
+}
+
+EncodeString::EncodeString(const QByteArray &excludeChars,
+ const QByteArray &includeChars) : m_excludeChars(excludeChars),
+ m_includeChars(includeChars)
+{
+}
+
+Item EncodeString::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ if(!item)
+ return CommonValues::EmptyString;
+
+ return AtomicString::fromValue(QString::fromAscii(QUrl::toPercentEncoding(item.stringValue(),
+ m_excludeChars,
+ m_includeChars).constData()));
+}
+
+const char *const EncodeForURIFN::include = "#!*'()";
+
+EncodeForURIFN::EncodeForURIFN() : EncodeString(QByteArray(), QByteArray::fromRawData(include, 6))
+{
+}
+
+const char *const IriToURIFN::exclude = "#-_!~*'();?@&=+$,[]/:%";
+
+IriToURIFN::IriToURIFN() : EncodeString(QByteArray::fromRawData(exclude, 22), QByteArray())
+{
+}
+
+const char *const EscapeHtmlURIFN::include = "?&[]%";
+const char *const EscapeHtmlURIFN::exclude = " :;=@!./+*()-,#$'";
+
+EscapeHtmlURIFN::EscapeHtmlURIFN() : EncodeString(QByteArray::fromRawData(exclude, 17),
+ QByteArray::fromRawData(include, 6))
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qstringvaluefns_p.h b/src/xmlpatterns/functions/qstringvaluefns_p.h
new file mode 100644
index 0000000000..b677d40bf9
--- /dev/null
+++ b/src/xmlpatterns/functions/qstringvaluefns_p.h
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_StringValueFNs_H
+#define Patternist_StringValueFNs_H
+
+#include <QByteArray>
+
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#string-value-functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 7.4 Functions on AtomicString Values</a>.
+ *
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:concat()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ConcatFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:string-join()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class StringJoinFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Optimization: when the cardinality of the sequence of items to join
+ * cannot be two or more, we have no effect and therefore rewrite
+ * ourselves to our first operand.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ };
+
+ /**
+ * @short Implements the function <tt>fn:substring()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class SubstringFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:string-length()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class StringLengthFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:normalize-space()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NormalizeSpaceFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:normalize-unicode()</tt>.
+ *
+ * What perhaps can be said significant with the implementation, is that it
+ * attempts to determine the normalization form at compile time, in order to
+ * reduce string work at runtime.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class NormalizeUnicodeFN : public FunctionCall
+ {
+ public:
+ /**
+ * Initializes private data.
+ */
+ NormalizeUnicodeFN();
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ int determineNormalizationForm(const DynamicContext::Ptr &context) const;
+ QString::NormalizationForm m_normForm;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:upper-case()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class UpperCaseFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:lower-case()</tt>.
+ *
+ * @short Implements the function <tt>fn:concat()</tt>.
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class LowerCaseFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:translate()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class TranslateFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Provides functionality for encoding strings. Sub-classed by various
+ * function implementations.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class EncodeString : public FunctionCall
+ {
+ public:
+ /**
+ * Evaluates its first operand. If it is the empty sequence, an empty string
+ * is returned. Otherwise, the item's string value is returned percent encoded
+ * as specified in this class's constructor.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ protected:
+ /**
+ * Encodes its operand with QUrl::toPercentEncoding(), with @p includeChars as
+ * the characters to encode, and @p excludeChars as the characters to not encode.
+ */
+ EncodeString(const QByteArray &excludeChars, const QByteArray &includeChars);
+
+ private:
+ const QByteArray m_excludeChars;
+ const QByteArray m_includeChars;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:encode-for-uri()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class EncodeForURIFN : public EncodeString
+ {
+ public:
+ /**
+ * Performs internal initialization.
+ */
+ EncodeForURIFN();
+
+ private:
+ static const char *const include;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:iri-to-uri()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class IriToURIFN : public EncodeString
+ {
+ public:
+ /**
+ * Performs internal initialization.
+ */
+ IriToURIFN();
+
+ private:
+ static const char *const exclude;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:escape-html-uri()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class EscapeHtmlURIFN : public EncodeString
+ {
+ public:
+ /**
+ * Performs internal initialization.
+ */
+ EscapeHtmlURIFN();
+
+ private:
+ static const char *const include;
+ static const char *const exclude;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qsubstringfns.cpp b/src/xmlpatterns/functions/qsubstringfns.cpp
new file mode 100644
index 0000000000..301f56a0dd
--- /dev/null
+++ b/src/xmlpatterns/functions/qsubstringfns.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+#include "qatomicstring_p.h"
+
+#include "qsubstringfns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ContainsFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operands.first()->evaluateSingleton(context));
+ QString str1;
+
+ if(op1)
+ str1 = op1.stringValue();
+
+ const Item op2(m_operands.at(1)->evaluateSingleton(context));
+ QString str2;
+
+ if(op2)
+ str2 = op2.stringValue();
+
+ if(str2.isEmpty())
+ return CommonValues::BooleanTrue;
+
+ if(str1.isEmpty())
+ return CommonValues::BooleanFalse;
+
+ return Boolean::fromValue(str1.contains(str2, caseSensitivity()));
+}
+
+Item StartsWithFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operands.first()->evaluateSingleton(context));
+ QString str1;
+
+ if(op1)
+ str1 = op1.stringValue();
+
+ const Item op2(m_operands.at(1)->evaluateSingleton(context));
+ QString str2;
+
+ if(op2)
+ str2 = op2.stringValue();
+
+ if(str2.isEmpty())
+ return CommonValues::BooleanTrue;
+
+ if(str1.isEmpty())
+ return CommonValues::BooleanFalse;
+
+ return Boolean::fromValue(str1.startsWith(str2, caseSensitivity()));
+}
+
+Item EndsWithFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operands.first()->evaluateSingleton(context));
+ QString str1;
+
+ if(op1)
+ str1 = op1.stringValue();
+
+ const Item op2(m_operands.at(1)->evaluateSingleton(context));
+ QString str2;
+
+ if(op2)
+ str2 = op2.stringValue();
+
+ if(str2.isEmpty())
+ return CommonValues::BooleanTrue;
+
+ if(str1.isEmpty())
+ return CommonValues::BooleanFalse;
+
+ return Boolean::fromValue(str1.endsWith(str2, caseSensitivity()));
+}
+
+Item SubstringBeforeFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operands.first()->evaluateSingleton(context));
+ QString str1;
+
+ if(op1)
+ str1 = op1.stringValue();
+
+ const Item op2(m_operands.at(1)->evaluateSingleton(context));
+ QString str2;
+
+ if(op2)
+ str2 = op2.stringValue();
+
+ const int pos = str1.indexOf(str2);
+ if(pos == -1)
+ return CommonValues::EmptyString;
+
+ return AtomicString::fromValue(QString(str1.left(pos)));
+}
+
+Item SubstringAfterFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operands.first()->evaluateSingleton(context));
+ QString str1;
+
+ if(op1)
+ str1 = op1.stringValue();
+
+ const Item op2(m_operands.at(1)->evaluateSingleton(context));
+ QString str2;
+
+ if(op2)
+ str2 = op2.stringValue();
+
+ if(str2.isEmpty())
+ {
+ if(op1)
+ return op1;
+ else
+ return CommonValues::EmptyString;
+ }
+
+ const int pos = str1.indexOf(str2);
+
+ if(pos == -1)
+ return CommonValues::EmptyString;
+
+ return AtomicString::fromValue(QString(str1.right(str1.length() - (pos + str2.length()))));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qsubstringfns_p.h b/src/xmlpatterns/functions/qsubstringfns_p.h
new file mode 100644
index 0000000000..292676464b
--- /dev/null
+++ b/src/xmlpatterns/functions/qsubstringfns_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SubStringFNs_H
+#define Patternist_SubStringFNs_H
+
+#include "qcomparescaseaware_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#substring.functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 7.5 Functions Based on Substring Matching</a>.
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:contains()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class ContainsFN : public ComparesCaseAware
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:starts-with()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class StartsWithFN : public ComparesCaseAware
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:ends-with()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class EndsWithFN : public ComparesCaseAware
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:substring-before()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class SubstringBeforeFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:substring-after()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class SubstringAfterFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qsystempropertyfn.cpp b/src/xmlpatterns/functions/qsystempropertyfn.cpp
new file mode 100644
index 0000000000..edd413d24a
--- /dev/null
+++ b/src/xmlpatterns/functions/qsystempropertyfn.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicstring_p.h"
+#include "qqnameconstructor_p.h"
+
+#include "qsystempropertyfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item SystemPropertyFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QString lexQName(m_operands.first()->evaluateSingleton(context).stringValue());
+
+ const QXmlName name
+ (QNameConstructor::expandQName<DynamicContext::Ptr,
+ ReportContext::XTDE1390,
+ ReportContext::XTDE1390>(lexQName,
+ context,
+ staticNamespaces(), this));
+
+ return AtomicString::fromValue(retrieveProperty(name));
+}
+
+QString SystemPropertyFN::retrieveProperty(const QXmlName name)
+{
+ if(name.namespaceURI() != StandardNamespaces::xslt)
+ return QString();
+
+ switch(name.localName())
+ {
+ case StandardLocalNames::version:
+ /*
+ * The supported XSL-T version.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#system-property">The Note paragraph
+ * at the very end of XSL Transformations (XSLT) Version 2.0,
+ * 16.6.5 system-property</a>
+ */
+ return QString::number(1.20);
+ case StandardLocalNames::vendor:
+ return QLatin1String("Nokia Corporation and/or its subsidiary(-ies), a Nokia Company");
+ case StandardLocalNames::vendor_url:
+ return QLatin1String("http://qtsoftware.com/");
+ case StandardLocalNames::product_name:
+ return QLatin1String("QtXmlPatterns");
+ case StandardLocalNames::product_version:
+ return QLatin1String("0.1");
+ case StandardLocalNames::is_schema_aware:
+ /* Fallthrough. */
+ case StandardLocalNames::supports_backwards_compatibility:
+ /* Fallthrough. */
+ case StandardLocalNames::supports_serialization:
+ /* Fallthrough. */
+ return QLatin1String("no");
+ default:
+ return QString();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qsystempropertyfn_p.h b/src/xmlpatterns/functions/qsystempropertyfn_p.h
new file mode 100644
index 0000000000..3b12edbaec
--- /dev/null
+++ b/src/xmlpatterns/functions/qsystempropertyfn_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SystemPropertyFN_H
+#define Patternist_SystemPropertyFN_H
+
+#include "qstaticnamespacescontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XSL-T 2.0's XPath function <tt>fn:system-property()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#system-property">XSL Transformations
+ * (XSLT) Version 2.0, 16.6.5 system-property</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class SystemPropertyFN : public StaticNamespacesContainer
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ private:
+ /**
+ * Returns a string representation for @p property as defined
+ * for the system properties in "XSL Transformations (XSLT)
+ * Version 2.0, 16.6.5 system-property". Hence, this function
+ * handles only the properties specified in the XSL namespace, and returns
+ * an empty string if an unrecognized property is asked for.
+ */
+ static QString retrieveProperty(const QXmlName name);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qtimezonefns.cpp b/src/xmlpatterns/functions/qtimezonefns.cpp
new file mode 100644
index 0000000000..1968ffb5ca
--- /dev/null
+++ b/src/xmlpatterns/functions/qtimezonefns.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractdatetime_p.h"
+#include "qcontextfns_p.h"
+#include "qdate_p.h"
+#include "qschemadatetime_p.h"
+#include "qdaytimeduration_p.h"
+#include "qpatternistlocale_p.h"
+#include "qschematime_p.h"
+
+#include "qtimezonefns_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item AdjustTimezone::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ enum
+ {
+ /**
+ * The maximum zone offset, @c PT14H, in milli seconds.
+ */
+ MSecLimit = 14 * 60/*M*/ * 60/*S*/ * 1000/*ms*/
+ };
+
+
+ const Item arg(m_operands.first()->evaluateSingleton(context));
+ if(!arg)
+ return Item();
+
+ QDateTime dt(arg.as<AbstractDateTime>()->toDateTime());
+ // TODO DT dt.setDateOnly(false);
+ Q_ASSERT(dt.isValid());
+ DayTimeDuration::Ptr tz;
+
+ if(m_operands.count() == 2)
+ tz = DayTimeDuration::Ptr(m_operands.at(1)->evaluateSingleton(context).as<DayTimeDuration>());
+ else
+ tz = context->implicitTimezone();
+
+ if(tz)
+ {
+ const MSecondCountProperty tzMSecs = tz->value();
+
+ if(tzMSecs % (1000 * 60) != 0)
+ {
+ context->error(QtXmlPatterns::tr("A zone offset must be in the "
+ "range %1..%2 inclusive. %3 is "
+ "out of range.")
+ .arg(formatData("-PT14H"))
+ .arg(formatData("PT14H"))
+ .arg(formatData(tz->stringValue())),
+ ReportContext::FODT0003, this);
+ return Item();
+ }
+ else if(tzMSecs > MSecLimit ||
+ tzMSecs < -MSecLimit)
+ {
+ context->error(QtXmlPatterns::tr("%1 is not a whole number of minutes.")
+ .arg(formatData(tz->stringValue())),
+ ReportContext::FODT0003, this);
+ return Item();
+ }
+
+ const SecondCountProperty tzSecs = tzMSecs / 1000;
+
+ if(dt.timeSpec() == Qt::LocalTime) /* $arg has no time zone. */
+ {
+ /* "If $arg does not have a timezone component and $timezone is not
+ * the empty sequence, then the result is $arg with $timezone as
+ * the timezone component." */
+ //dt.setTimeSpec(QDateTime::Spec(QDateTime::OffsetFromUTC, tzSecs));
+ dt.setUtcOffset(tzSecs);
+ Q_ASSERT(dt.isValid());
+ return createValue(dt);
+ }
+ else
+ {
+ /* "If $arg has a timezone component and $timezone is not the empty sequence,
+ * then the result is an xs:dateTime value with a timezone component of
+ * $timezone that is equal to $arg." */
+ dt = dt.toUTC();
+ dt = dt.addSecs(tzSecs);
+ //dt.setTimeSpec(QDateTime::Spec(QDateTime::OffsetFromUTC, tzSecs));
+ dt.setUtcOffset(tzSecs);
+ Q_ASSERT(dt.isValid());
+ return createValue(dt);
+ }
+ }
+ else
+ { /* $timezone is the empty sequence. */
+ if(dt.timeSpec() == Qt::LocalTime) /* $arg has no time zone. */
+ {
+ /* "If $arg does not have a timezone component and $timezone is
+ * the empty sequence, then the result is $arg." */
+ return arg;
+ }
+ else
+ {
+ /* "If $arg has a timezone component and $timezone is the empty sequence,
+ * then the result is the localized value of $arg without its timezone component." */
+ dt.setTimeSpec(Qt::LocalTime);
+ return createValue(dt);
+ }
+ }
+}
+
+Item AdjustDateTimeToTimezoneFN::createValue(const QDateTime &dt) const
+{
+ Q_ASSERT(dt.isValid());
+ return DateTime::fromDateTime(dt);
+}
+
+Item AdjustDateToTimezoneFN::createValue(const QDateTime &dt) const
+{
+ Q_ASSERT(dt.isValid());
+ return Date::fromDateTime(dt);
+}
+
+Item AdjustTimeToTimezoneFN::createValue(const QDateTime &dt) const
+{
+ Q_ASSERT(dt.isValid());
+ return SchemaTime::fromDateTime(dt);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qtimezonefns_p.h b/src/xmlpatterns/functions/qtimezonefns_p.h
new file mode 100644
index 0000000000..a6373e4f0b
--- /dev/null
+++ b/src/xmlpatterns/functions/qtimezonefns_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TimezoneFNs_H
+#define Patternist_TimezoneFNs_H
+
+#include "qatomiccomparator_p.h"
+#include "qfunctioncall_p.h"
+
+/**
+ * @file
+ * @short Contains classes implementing the functions found in
+ * <a href="http://www.w3.org/TR/xpath-functions/#timezone.functions">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 10.7 Timezone Adjustment on Dates and SchemaTime Values</a>.
+ * @ingroup Patternist_functions
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for classes implementing functions changing the timezone
+ * on values.
+ *
+ * It would be possible to implement this with the Curiously Recurring Template Pattern, in order
+ * to avoid the virtual call dispatching that is done via createValue(). However, these are not
+ * very hot code paths and evaluateSingleton() is quite large, which would lead to heavy code
+ * expansion.
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern">Curiously
+ * Recurring Template Pattern, Wikipedia, the free encyclopedia</a>
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class AdjustTimezone : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ protected:
+ virtual Item createValue(const QDateTime &dt) const = 0;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:adjust-dateTime-to-timezone()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class AdjustDateTimeToTimezoneFN : public AdjustTimezone
+ {
+ protected:
+ virtual Item createValue(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:adjust-dateTime-to-timezone()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class AdjustDateToTimezoneFN : public AdjustTimezone
+ {
+ protected:
+ virtual Item createValue(const QDateTime &dt) const;
+ };
+
+ /**
+ * @short Implements the function <tt>fn:adjust-time-to-timezone()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class AdjustTimeToTimezoneFN : public AdjustTimezone
+ {
+ protected:
+ virtual Item createValue(const QDateTime &dt) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qtracefn.cpp b/src/xmlpatterns/functions/qtracefn.cpp
new file mode 100644
index 0000000000..c7f193e5ed
--- /dev/null
+++ b/src/xmlpatterns/functions/qtracefn.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qtracefn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ /**
+ * @short TraceCallback is a MappingCallback and takes care of
+ * the tracing of each individual item.
+ *
+ * Because Patternist must be thread safe, TraceFN creates a TraceCallback
+ * each time the function is evaluated. In other words, TraceFN, which is
+ * an Expression sub class, can't modify its members, but MappingCallback
+ * does not have this limitation since it's created on a per evaluation basis.
+ *
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class TraceCallback : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<TraceCallback> Ptr;
+
+ inline TraceCallback(const QString &msg) : m_position(0),
+ m_msg(msg)
+ {
+ }
+
+ /**
+ * Performs the actual tracing.
+ */
+ Item mapToItem(const Item &item,
+ const DynamicContext::Ptr &context)
+ {
+ QTextStream out(stderr);
+ ++m_position;
+ if(m_position == 1)
+ {
+ if(item)
+ {
+ out << qPrintable(m_msg)
+ << " : "
+ << qPrintable(item.stringValue());
+ }
+ else
+ {
+ out << qPrintable(m_msg)
+ << " : ("
+ << qPrintable(formatType(context->namePool(), CommonSequenceTypes::Empty))
+ << ")\n";
+ return Item();
+ }
+ }
+ else
+ {
+ out << qPrintable(item.stringValue())
+ << '['
+ << m_position
+ << "]\n";
+ }
+
+ return item;
+ }
+
+ private:
+ xsInteger m_position;
+ const QString m_msg;
+ };
+}
+
+Item::Iterator::Ptr TraceFN::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const QString msg(m_operands.last()->evaluateSingleton(context).stringValue());
+
+ return makeItemMappingIterator<Item>(TraceCallback::Ptr(new TraceCallback(msg)),
+ m_operands.first()->evaluateSequence(context),
+ context);
+}
+
+Item TraceFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QString msg(m_operands.last()->evaluateSingleton(context).stringValue());
+ const Item item(m_operands.first()->evaluateSingleton(context));
+
+ return TraceCallback::Ptr(new TraceCallback(msg))->mapToItem(item, context);
+}
+
+SequenceType::Ptr TraceFN::staticType() const
+{
+ return m_operands.first()->staticType();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qtracefn_p.h b/src/xmlpatterns/functions/qtracefn_p.h
new file mode 100644
index 0000000000..667d5c24d9
--- /dev/null
+++ b/src/xmlpatterns/functions/qtracefn_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TraceFN_H
+#define Patternist_TraceFN_H
+
+#include "qfunctioncall_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the function <tt>fn:trace()</tt>.
+ * @ingroup Patternist_functions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class TraceFN : public FunctionCall
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Formally speaking, the type inference is:
+ *
+@verbatim
+statEnv |- (FN-URI,"trace")(Type) : prime(Type) * quantifier(Type)
+@endverbatim
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-semantics/#sec_fn_reverse">XQuery 1.0
+ * and XPath 2.0 Formal Semantics, 7.2.12 The fn:reverse function</a>, for
+ * an example of where the type inference is used
+ * @returns the static type of the function's first argument.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qtypeavailablefn.cpp b/src/xmlpatterns/functions/qtypeavailablefn.cpp
new file mode 100644
index 0000000000..d120df87d8
--- /dev/null
+++ b/src/xmlpatterns/functions/qtypeavailablefn.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qqnameconstructor_p.h"
+
+#include "qtypeavailablefn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item TypeAvailableFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QString lexQName(m_operands.first()->evaluateSingleton(context).stringValue());
+
+ const QXmlName name
+ (QNameConstructor::expandQName<DynamicContext::Ptr,
+ ReportContext::XTDE1428,
+ ReportContext::XTDE1428>(lexQName,
+ context,
+ staticNamespaces(),
+ this));
+
+
+ return Boolean::fromValue(m_schemaTypeFactory->types().contains(name));
+}
+
+Expression::Ptr TypeAvailableFN::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_schemaTypeFactory = context->schemaDefinitions();
+ return StaticNamespacesContainer::typeCheck(context, reqType);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qtypeavailablefn_p.h b/src/xmlpatterns/functions/qtypeavailablefn_p.h
new file mode 100644
index 0000000000..d37c3069fa
--- /dev/null
+++ b/src/xmlpatterns/functions/qtypeavailablefn_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TypeAvailableFN_H
+#define Patternist_TypeAvailableFN_H
+
+#include "qschematypefactory_p.h"
+#include "qstaticnamespacescontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XSL-T 2.0's XPath function <tt>fn:type-available()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#function-function-available">XSL Transformations
+ * (XSLT) Version 2.0, 18.1.1 Testing Availability of Functions</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class TypeAvailableFN : public StaticNamespacesContainer
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Reimplemented to store data from the @p context which is needed at runtime.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ private:
+ SchemaTypeFactory::Ptr m_schemaTypeFactory;
+ };
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp b/src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp
new file mode 100644
index 0000000000..269b81ea12
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicstring_p.h"
+
+#include "qunparsedentitypublicidfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item UnparsedEntityPublicIDFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ checkTargetNode(context->contextItem().asNode(), context, ReportContext::XTDE1380);
+ return AtomicString::fromValue(QString());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h b/src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h
new file mode 100644
index 0000000000..e9af810153
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UnparsedEntityPublicID_H
+#define Patternist_UnparsedEntityPublicID_H
+
+#include "qcontextnodechecker_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XSL-T 2.0's XPath function <tt>fn:unparsed-entity-public-id()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#function-unparsed-entity-uri">XSL Transformations
+ * (XSLT) Version 2.0, 16.6.3 unparsed-entity-public-id</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class UnparsedEntityPublicIDFN : public ContextNodeChecker
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qunparsedentityurifn.cpp b/src/xmlpatterns/functions/qunparsedentityurifn.cpp
new file mode 100644
index 0000000000..80580121fc
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentityurifn.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+
+#include "qunparsedentityurifn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item UnparsedEntityURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ checkTargetNode(context->contextItem().asNode(), context, ReportContext::XTDE1370);
+ return toItem(AnyURI::fromValue(QUrl()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qunparsedentityurifn_p.h b/src/xmlpatterns/functions/qunparsedentityurifn_p.h
new file mode 100644
index 0000000000..7dcd69f942
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedentityurifn_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UnparsedEntityURIFN_H
+#define Patternist_UnparsedEntityURIFN_H
+
+#include "qcontextnodechecker_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XSL-T 2.0's XPath function <tt>fn:unparsed-entity-uri()</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#function-unparsed-entity-uri">XSL Transformations
+ * (XSLT) Version 2.0, 16.6.2 unparsed-entity-uri</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class UnparsedEntityURIFN : public ContextNodeChecker
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qunparsedtextavailablefn.cpp b/src/xmlpatterns/functions/qunparsedtextavailablefn.cpp
new file mode 100644
index 0000000000..c092240254
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextavailablefn.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+
+#include "qunparsedtextavailablefn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool UnparsedTextAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2);
+ const Item href(m_operands.first()->evaluateSingleton(context));
+ if(!href)
+ return Item();
+
+ bool isValid = false;
+ const QUrl mayRela(AnyURI::toQUrl<ReportContext::XTDE1170>(href.stringValue(),
+ context,
+ this,
+ &isValid));
+
+ if(!isValid)
+ return false;
+
+ const QUrl uri(context->resolveURI(mayRela, staticBaseURI()));
+
+ /* fn:unparsed-text() will raise an error on this. */
+ if(uri.hasFragment())
+ return false;
+
+ QString encoding;
+
+ if(m_operands.count() == 2)
+ {
+ const Item encodingArg(m_operands.at(1)->evaluateSingleton(context));
+ if(encodingArg)
+ encoding = encodingArg.stringValue();
+ }
+
+ Q_ASSERT(uri.isValid() && !uri.isRelative());
+ return context->resourceLoader()->isUnparsedTextAvailable(uri, encoding);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qunparsedtextavailablefn_p.h b/src/xmlpatterns/functions/qunparsedtextavailablefn_p.h
new file mode 100644
index 0000000000..938a68a148
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextavailablefn_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UnparsedTextAvailableFN_H
+#define Patternist_UnparsedTextAvailableFN_H
+
+#include "qstaticbaseuricontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:unparsed-text-available()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL
+ * Transformations (XSLT) Version 2.0, 16.2 unparsed-text</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @since 4.5
+ */
+ class UnparsedTextAvailableFN : public StaticBaseUriContainer
+ {
+ public:
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qunparsedtextfn.cpp b/src/xmlpatterns/functions/qunparsedtextfn.cpp
new file mode 100644
index 0000000000..0400c944f2
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextfn.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+
+#include "qunparsedtextfn_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item UnparsedTextFN::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2);
+ const Item href(m_operands.first()->evaluateSingleton(context));
+ if(!href)
+ return Item();
+
+ const QUrl mayRela(AnyURI::toQUrl<ReportContext::XTDE1170>(href.stringValue(),
+ context,
+ this));
+
+ const QUrl uri(context->resolveURI(mayRela, staticBaseURI()));
+
+ if(uri.hasFragment())
+ {
+ context->error(QtXmlPatterns::tr("The URI cannot have a fragment"),
+ ReportContext::XTDE1170, this);
+ }
+
+ QString encoding;
+
+ if(m_operands.count() == 2)
+ {
+ const Item encodingArg(m_operands.at(1)->evaluateSingleton(context));
+ if(encodingArg)
+ encoding = encodingArg.stringValue();
+ }
+
+ Q_ASSERT(uri.isValid() && !uri.isRelative());
+ return context->resourceLoader()->openUnparsedText(uri, encoding, context, this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qunparsedtextfn_p.h b/src/xmlpatterns/functions/qunparsedtextfn_p.h
new file mode 100644
index 0000000000..0661c273af
--- /dev/null
+++ b/src/xmlpatterns/functions/qunparsedtextfn_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UnparsedTextFN_H
+#define Patternist_UnparsedTextFN_H
+
+#include "qstaticbaseuricontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the function <tt>fn:unparsed-text()</tt>.
+ *
+ * @ingroup Patternist_functions
+ * @see <a href="http://www.w3.org/TR/xslt20/#unparsed-text">XSL
+ * Transformations (XSLT) Version 2.0, 16.2 unparsed-text</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @since 4.5
+ */
+ class UnparsedTextFN : public StaticBaseUriContainer
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qxpath10corefunctions.cpp b/src/xmlpatterns/functions/qxpath10corefunctions.cpp
new file mode 100644
index 0000000000..787eac013c
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath10corefunctions.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qpatternistlocale_p.h"
+#include "qxmlname.h"
+
+/* Functions */
+#include "qaccessorfns_p.h"
+#include "qaggregatefns_p.h"
+#include "qbooleanfns_p.h"
+#include "qcomparestringfns_p.h"
+#include "qcontextfns_p.h"
+#include "qnodefns_p.h"
+#include "qnumericfns_p.h"
+#include "qsequencefns_p.h"
+#include "qsequencegeneratingfns_p.h"
+#include "qstringvaluefns_p.h"
+#include "qsubstringfns_p.h"
+
+#include "qxpath10corefunctions_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr XPath10CoreFunctions::retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const
+{
+ Q_ASSERT(sign);
+
+ Expression::Ptr fn;
+#define testFN(ln, cname) else if(name.localName() == StandardLocalNames::ln) fn = Expression::Ptr(new cname())
+
+ if(false) /* Dummy for the macro handling. Will be optimized away anyway. */
+ return Expression::Ptr();
+ /* Alphabetic order. */
+ testFN(boolean, BooleanFN);
+ testFN(ceiling, CeilingFN);
+ testFN(concat, ConcatFN);
+ testFN(contains, ContainsFN);
+ testFN(count, CountFN);
+ testFN(False, FalseFN);
+ testFN(floor, FloorFN);
+ testFN(id, IdFN);
+ testFN(lang, LangFN);
+ testFN(last, LastFN);
+ testFN(local_name, LocalNameFN);
+ testFN(name, NameFN);
+ testFN(namespace_uri, NamespaceURIFN);
+ testFN(normalize_space, NormalizeSpaceFN);
+ testFN(Not, NotFN);
+ testFN(number, NumberFN);
+ testFN(position, PositionFN);
+ testFN(round, RoundFN);
+ testFN(starts_with, StartsWithFN);
+ testFN(string, StringFN);
+ testFN(string_length, StringLengthFN);
+ testFN(substring, SubstringFN);
+ testFN(substring_after, SubstringAfterFN);
+ testFN(substring_before, SubstringBeforeFN);
+ testFN(sum, SumFN);
+ testFN(translate, TranslateFN);
+ testFN(True, TrueFN);
+#undef testFN
+
+ Q_ASSERT(fn);
+ fn->setOperands(args);
+ fn->as<FunctionCall>()->setSignature(sign);
+
+ return fn;
+}
+
+FunctionSignature::Ptr XPath10CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name)
+{
+ if(StandardNamespaces::fn != name.namespaceURI())
+ return FunctionSignature::Ptr();
+
+ FunctionSignature::Ptr s(functionSignatures().value(name));
+
+ if(!s)
+ {
+ const QXmlName::LocalNameCode localName(name.localName());
+
+ /* Alphabetic order. */
+ if(StandardLocalNames::boolean == localName)
+ {
+ s = addFunction(StandardLocalNames::boolean, 1, 1, CommonSequenceTypes::ExactlyOneBoolean);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::EBV);
+ }
+ else if(StandardLocalNames::ceiling == localName)
+ {
+ s = addFunction(StandardLocalNames::ceiling, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric);
+ }
+ else if(StandardLocalNames::concat == localName)
+ {
+ s = addFunction(StandardLocalNames::concat, 2, FunctionSignature::UnlimitedArity,
+ CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneAtomicType);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneAtomicType);
+ }
+ else if(StandardLocalNames::contains == localName)
+ {
+ s = addFunction(StandardLocalNames::contains, 2, 3, CommonSequenceTypes::ExactlyOneBoolean,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::count == localName)
+ {
+ s = addFunction(StandardLocalNames::count, 1, 1, CommonSequenceTypes::ExactlyOneInteger, Expression::IDCountFN);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::False == localName)
+ {
+ s = addFunction(StandardLocalNames::False, 0, 0, CommonSequenceTypes::ExactlyOneBoolean);
+ }
+ else if(StandardLocalNames::floor == localName)
+ {
+ s = addFunction(StandardLocalNames::floor, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric);
+ }
+ else if(StandardLocalNames::id == localName)
+ {
+ s = addFunction(StandardLocalNames::id, 1, 2, CommonSequenceTypes::ZeroOrMoreElements,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "idrefs"), CommonSequenceTypes::ZeroOrMoreStrings);
+ s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode);
+ }
+ else if(StandardLocalNames::lang == localName)
+ {
+ s = addFunction(StandardLocalNames::lang, 1, 2, CommonSequenceTypes::ExactlyOneBoolean,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "testLang"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode);
+ }
+ else if(StandardLocalNames::last == localName)
+ {
+ s = addFunction(StandardLocalNames::last, 0, 0, CommonSequenceTypes::ExactlyOneInteger,
+ Expression::DisableElimination | Expression::RequiresFocus);
+ }
+ else if(StandardLocalNames::local_name == localName)
+ {
+ s = addFunction(StandardLocalNames::local_name, 0, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::name == localName)
+ {
+ s = addFunction(StandardLocalNames::name, 0, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::namespace_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::namespace_uri, 0, 1, CommonSequenceTypes::ExactlyOneAnyURI,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::normalize_space == localName)
+ {
+ s = addFunction(StandardLocalNames::normalize_space, 0, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::Not == localName)
+ {
+ s = addFunction(StandardLocalNames::Not, 1, 1, CommonSequenceTypes::ExactlyOneBoolean);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::EBV);
+ }
+ else if(StandardLocalNames::number == localName)
+ {
+ s = addFunction(StandardLocalNames::number, 0, 1, CommonSequenceTypes::ExactlyOneDouble,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneAtomicType);
+ }
+ else if(StandardLocalNames::position == localName)
+ {
+ s = addFunction(StandardLocalNames::position, 0, 0, CommonSequenceTypes::ExactlyOneInteger,
+ Expression::DisableElimination | Expression::RequiresFocus);
+ }
+ else if(StandardLocalNames::round == localName)
+ {
+ s = addFunction(StandardLocalNames::round, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric);
+ }
+ else if(StandardLocalNames::starts_with == localName)
+ {
+ s = addFunction(StandardLocalNames::starts_with, 2, 3, CommonSequenceTypes::ExactlyOneBoolean,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::string == localName)
+ {
+ s = addFunction(StandardLocalNames::string, 0, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneItem);
+ }
+ else if(StandardLocalNames::string_length == localName)
+ {
+ s = addFunction(StandardLocalNames::string_length, 0, 1,
+ CommonSequenceTypes::ExactlyOneInteger,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::substring == localName)
+ {
+ s = addFunction(StandardLocalNames::substring, 2, 3, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "sourceString"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "startingLoc"), CommonSequenceTypes::ExactlyOneDouble);
+ s->appendArgument(argument(np, "length"), CommonSequenceTypes::ExactlyOneDouble);
+ }
+ else if(StandardLocalNames::substring_after == localName)
+ {
+ s = addFunction(StandardLocalNames::substring_after, 2, 3, CommonSequenceTypes::ExactlyOneString,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::substring_before == localName)
+ {
+ s = addFunction(StandardLocalNames::substring_before, 2, 3, CommonSequenceTypes::ExactlyOneString,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::sum == localName)
+ {
+ s = addFunction(StandardLocalNames::sum, 1, 2, CommonSequenceTypes::ZeroOrOneAtomicType);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ s->appendArgument(argument(np, "zero"), CommonSequenceTypes::ZeroOrOneAtomicType);
+ }
+ else if(StandardLocalNames::translate == localName)
+ {
+ s = addFunction(StandardLocalNames::translate, 3, 3, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "mapString"), CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "transString"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::True == localName)
+ {
+ s = addFunction(StandardLocalNames::True, 0, 0, CommonSequenceTypes::ExactlyOneBoolean);
+ }
+ }
+
+ return s;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qxpath10corefunctions_p.h b/src/xmlpatterns/functions/qxpath10corefunctions_p.h
new file mode 100644
index 0000000000..388749525f
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath10corefunctions_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XPath10CoreFunctions_H
+#define Patternist_XPath10CoreFunctions_H
+
+#include "qabstractfunctionfactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Supplies the functions available in XPath 1.0.
+ *
+ * @ingroup Patternist_functions
+ * @see <a href="http://www.w3.org/TR/xpath.html#corelib">XML Path Language (XPath)
+ * Version 1.0, 4 Core Function Library</a>
+ * @see XPath20CoreFunctions
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class XPath10CoreFunctions : public AbstractFunctionFactory
+ {
+ protected:
+ /**
+ * This function is responsible for creating the actual Expression, corresponding
+ * to @p localName and the function signature @p sign. It is called by
+ * createFunctionCall(), once it have been determined the function actually
+ * exists and have the correct arity.
+ */
+ virtual Expression::Ptr retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const;
+ virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qxpath20corefunctions.cpp b/src/xmlpatterns/functions/qxpath20corefunctions.cpp
new file mode 100644
index 0000000000..384a77c63e
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath20corefunctions.cpp
@@ -0,0 +1,748 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qatomizer_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcardinalityverifier_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qemptysequence_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qxmlname.h"
+#include "qatomicstring_p.h"
+
+/* Functions */
+#include "qaccessorfns_p.h"
+#include "qaggregatefns_p.h"
+#include "qassemblestringfns_p.h"
+#include "qbooleanfns_p.h"
+#include "qcomparestringfns_p.h"
+#include "qcomparingaggregator_p.h"
+#include "qcontextfns_p.h"
+#include "qdatetimefn_p.h"
+#include "qdatetimefns_p.h"
+#include "qdeepequalfn_p.h"
+#include "qerrorfn_p.h"
+#include "qnodefns_p.h"
+#include "qnumericfns_p.h"
+#include "qpatternmatchingfns_p.h"
+#include "qqnamefns_p.h"
+#include "qresolveurifn_p.h"
+#include "qsequencefns_p.h"
+#include "qsequencegeneratingfns_p.h"
+#include "qstringvaluefns_p.h"
+#include "qsubstringfns_p.h"
+#include "qtimezonefns_p.h"
+#include "qtracefn_p.h"
+
+#include "qxpath20corefunctions_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr XPath20CoreFunctions::retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const
+{
+ Q_ASSERT(sign);
+
+ Expression::Ptr fn;
+#define testFN(ln, cname) else if(name.localName() == StandardLocalNames::ln) fn = Expression::Ptr(new cname())
+
+ if(false) /* Dummy for the macro handling. Will be optimized away anyway. */
+ return Expression::Ptr();
+ /* Alphabetic order. */
+ testFN(QName, QNameFN);
+ testFN(abs, AbsFN);
+ testFN(adjust_date_to_timezone, AdjustDateToTimezoneFN);
+ testFN(adjust_dateTime_to_timezone, AdjustDateTimeToTimezoneFN);
+ testFN(adjust_time_to_timezone, AdjustTimeToTimezoneFN);
+ testFN(avg, AvgFN);
+ testFN(base_uri, BaseURIFN);
+ testFN(codepoint_equal, CodepointEqualFN);
+ testFN(codepoints_to_string, CodepointsToStringFN);
+ testFN(collection, CollectionFN);
+ testFN(compare, CompareFN);
+ testFN(current_date, CurrentDateFN);
+ testFN(current_dateTime, CurrentDateTimeFN);
+ testFN(current_time, CurrentTimeFN);
+ testFN(dateTime, DateTimeFN);
+ testFN(day_from_date, DayFromAbstractDateTimeFN);
+ testFN(day_from_dateTime, DayFromAbstractDateTimeFN);
+ testFN(days_from_duration, DaysFromDurationFN);
+ testFN(deep_equal, DeepEqualFN);
+ testFN(default_collation, DefaultCollationFN);
+ testFN(distinct_values, DistinctValuesFN);
+ testFN(doc, DocFN);
+ testFN(doc_available, DocAvailableFN);
+ testFN(document_uri, DocumentURIFN);
+ testFN(empty, Existence<Expression::IDEmptyFN>);
+ testFN(encode_for_uri, EncodeForURIFN);
+ testFN(ends_with, EndsWithFN);
+ testFN(error, ErrorFN);
+ testFN(escape_html_uri, EscapeHtmlURIFN);
+ testFN(exists, Existence<Expression::IDExistsFN>);
+ testFN(hours_from_dateTime, HoursFromAbstractDateTimeFN);
+ testFN(hours_from_duration, HoursFromDurationFN);
+ testFN(hours_from_time, HoursFromAbstractDateTimeFN);
+ testFN(idref, IdrefFN);
+ testFN(implicit_timezone, ImplicitTimezoneFN);
+ testFN(in_scope_prefixes, InScopePrefixesFN);
+ testFN(index_of, IndexOfFN);
+ testFN(insert_before, InsertBeforeFN);
+ testFN(iri_to_uri, IriToURIFN);
+ testFN(local_name_from_QName, LocalNameFromQNameFN);
+ testFN(lower_case, LowerCaseFN);
+ testFN(matches, MatchesFN);
+ testFN(max, MaxFN);
+ testFN(min, MinFN);
+ testFN(minutes_from_dateTime, MinutesFromAbstractDateTimeFN);
+ testFN(minutes_from_duration, MinutesFromDurationFN);
+ testFN(minutes_from_time, MinutesFromAbstractDateTimeFN);
+ testFN(month_from_date, MonthFromAbstractDateTimeFN);
+ testFN(month_from_dateTime, MonthFromAbstractDateTimeFN);
+ testFN(months_from_duration, MonthsFromDurationFN);
+ testFN(namespace_uri_for_prefix, NamespaceURIForPrefixFN);
+ testFN(namespace_uri_from_QName, NamespaceURIFromQNameFN);
+ testFN(nilled, NilledFN);
+ testFN(node_name, NodeNameFN);
+ testFN(normalize_unicode, NormalizeUnicodeFN);
+ testFN(prefix_from_QName, PrefixFromQNameFN);
+ testFN(remove, RemoveFN);
+ testFN(replace, ReplaceFN);
+ testFN(resolve_QName, ResolveQNameFN);
+ testFN(resolve_uri, ResolveURIFN);
+ testFN(generic_string_join, StringJoinFN);
+ testFN(reverse, ReverseFN);
+ testFN(root, RootFN);
+ testFN(round_half_to_even, RoundHalfToEvenFN);
+ testFN(seconds_from_dateTime, SecondsFromAbstractDateTimeFN);
+ testFN(seconds_from_duration, SecondsFromDurationFN);
+ testFN(seconds_from_time, SecondsFromAbstractDateTimeFN);
+ testFN(static_base_uri, StaticBaseURIFN);
+ testFN(string_join, StringJoinFN);
+ testFN(string_to_codepoints, StringToCodepointsFN);
+ testFN(subsequence, SubsequenceFN);
+ testFN(timezone_from_date, TimezoneFromAbstractDateTimeFN);
+ testFN(timezone_from_dateTime, TimezoneFromAbstractDateTimeFN);
+ testFN(timezone_from_time, TimezoneFromAbstractDateTimeFN);
+ testFN(tokenize, TokenizeFN);
+ testFN(trace, TraceFN);
+ testFN(upper_case, UpperCaseFN);
+ testFN(year_from_date, YearFromAbstractDateTimeFN);
+ testFN(year_from_dateTime, YearFromAbstractDateTimeFN);
+ testFN(years_from_duration, YearsFromDurationFN);
+#undef testFN
+
+ if(fn)
+ {
+ fn->setOperands(args);
+ fn->as<FunctionCall>()->setSignature(sign);
+ }
+ else
+ {
+ /* Do the ones which are not FunctionCall sub-classes. The effect is
+ * that FunctionCall sub-classes has "automatic" type checking in the base
+ * class done from the background of their function signature, while
+ * these special classes are on their own, and must do it manually. */
+ if(name.localName() == StandardLocalNames::data)
+ fn = Expression::Ptr(new Atomizer(args.first()));
+ else if(name.localName() == StandardLocalNames::zero_or_one)
+ fn = Expression::Ptr(new CardinalityVerifier(args.first(), Cardinality::zeroOrOne(),
+ ReportContext::FORG0003));
+ else if(name.localName() == StandardLocalNames::one_or_more)
+ fn = Expression::Ptr(new CardinalityVerifier(args.first(), Cardinality::oneOrMore(),
+ ReportContext::FORG0004));
+ else if(name.localName() == StandardLocalNames::exactly_one)
+ fn = Expression::Ptr(new CardinalityVerifier(args.first(), Cardinality::exactlyOne(),
+ ReportContext::FORG0005));
+ else if(name.localName() == StandardLocalNames::unordered)
+ /* We don't make use of the unordered() function, so just pop in
+ * the arg. */
+ fn = args.first();
+ }
+
+ return fn;
+}
+
+FunctionSignature::Ptr XPath20CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np,
+ const QXmlName name)
+{
+ if(StandardNamespaces::fn != name.namespaceURI() && name.namespaceURI() != StandardNamespaces::InternalXSLT)
+ return FunctionSignature::Ptr();
+
+ FunctionSignature::Ptr s(functionSignatures().value(name));
+
+ if(!s)
+ {
+ const QXmlName::LocalNameCode localName = name.localName();
+
+ /* Alphabetic order. */
+ if(StandardLocalNames::QName == localName)
+ {
+ s = addFunction(StandardLocalNames::QName, 2, 2, CommonSequenceTypes::ExactlyOneQName);
+ s->appendArgument(argument(np, "paramURI"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "paramQName"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::abs == localName)
+ {
+ s = addFunction(StandardLocalNames::abs, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric);
+ }
+ else if(StandardLocalNames::adjust_date_to_timezone == localName)
+ {
+ s = addFunction(StandardLocalNames::adjust_date_to_timezone, 1, 2, CommonSequenceTypes::ZeroOrOneDate,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate);
+ s->appendArgument(argument(np, "timezone"), CommonSequenceTypes::ZeroOrOneDayTimeDuration);
+ }
+ else if(StandardLocalNames::adjust_dateTime_to_timezone == localName)
+ {
+ s = addFunction(StandardLocalNames::adjust_dateTime_to_timezone, 1, 2, CommonSequenceTypes::ZeroOrOneDateTime,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ s->appendArgument(argument(np, "timezone"), CommonSequenceTypes::ZeroOrOneDayTimeDuration);
+ }
+ else if(StandardLocalNames::adjust_time_to_timezone == localName)
+ {
+ s = addFunction(StandardLocalNames::adjust_time_to_timezone, 1, 2, CommonSequenceTypes::ZeroOrOneTime,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime);
+ s->appendArgument(argument(np, "timezone"), CommonSequenceTypes::ZeroOrOneDayTimeDuration);
+ }
+ else if(StandardLocalNames::avg == localName)
+ {
+ s = addFunction(StandardLocalNames::avg, 1, 1, CommonSequenceTypes::ZeroOrOneAtomicType,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ }
+ else if(StandardLocalNames::base_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::base_uri, 0, 1, CommonSequenceTypes::ZeroOrOneAnyURI,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::codepoint_equal == localName)
+ {
+ s = addFunction(StandardLocalNames::codepoint_equal, 2, 2, CommonSequenceTypes::ZeroOrOneBoolean);
+ s->appendArgument(argument(np, "comparand1"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "comparand2"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::codepoints_to_string == localName)
+ {
+ s = addFunction(StandardLocalNames::codepoints_to_string, 1, 1, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreIntegers);
+ }
+ else if(StandardLocalNames::collection == localName)
+ {
+ s = addFunction(StandardLocalNames::collection, 0, 1, CommonSequenceTypes::ZeroOrMoreNodes);
+ s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::compare == localName)
+ {
+ s = addFunction(StandardLocalNames::compare, 2, 3, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "comparand1"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "comparand2"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::current_date == localName)
+ {
+ s = addFunction(StandardLocalNames::current_date, 0, 0, CommonSequenceTypes::ExactlyOneDate,
+ Expression::DisableElimination);
+ }
+ else if(StandardLocalNames::current_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::current_dateTime, 0, 0, CommonSequenceTypes::ExactlyOneDateTime,
+ Expression::DisableElimination);
+ }
+ else if(StandardLocalNames::current_time == localName)
+ {
+ s = addFunction(StandardLocalNames::current_time, 0, 0, CommonSequenceTypes::ExactlyOneTime,
+ Expression::DisableElimination);
+ }
+ else if(StandardLocalNames::data == localName)
+ {
+ s = addFunction(StandardLocalNames::data, 1, 1, CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::dateTime, 2, 2, CommonSequenceTypes::ZeroOrOneDateTime);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneDate);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneTime);
+ }
+ else if(StandardLocalNames::day_from_date == localName)
+ {
+ s = addFunction(StandardLocalNames::day_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate);
+ }
+ else if(StandardLocalNames::day_from_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::day_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ }
+ else if(StandardLocalNames::days_from_duration == localName)
+ {
+ s = addFunction(StandardLocalNames::days_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration);
+ }
+ else if(StandardLocalNames::deep_equal == localName)
+ {
+ s = addFunction(StandardLocalNames::deep_equal, 2, 3, CommonSequenceTypes::ExactlyOneBoolean,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::default_collation == localName)
+ {
+ s = addFunction(StandardLocalNames::default_collation, 0, 0, CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::distinct_values == localName)
+ {
+ s = addFunction(StandardLocalNames::distinct_values, 1, 2, CommonSequenceTypes::ZeroOrMoreAtomicTypes,
+ Expression::LastOperandIsCollation |
+ Expression::EmptynessFollowsChild |
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::doc == localName)
+ {
+ s = addFunction(StandardLocalNames::doc, 1, 1, CommonSequenceTypes::ZeroOrOneDocumentNode, Expression::DisableElimination);
+ s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::doc_available == localName)
+ {
+ s = addFunction(StandardLocalNames::doc_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean, Expression::DisableElimination);
+ s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::document_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::document_uri, 1, 1, CommonSequenceTypes::ZeroOrOneAnyURI);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::empty == localName)
+ {
+ s = addFunction(StandardLocalNames::empty, 1, 1, CommonSequenceTypes::ExactlyOneBoolean, Expression::IDEmptyFN);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::encode_for_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::encode_for_uri, 1, 1, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "uriPart"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::ends_with == localName)
+ {
+ s = addFunction(StandardLocalNames::ends_with, 2, 3, CommonSequenceTypes::ExactlyOneBoolean,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::error == localName)
+ {
+ s = addFunction(StandardLocalNames::error, 0, 3, CommonSequenceTypes::None,
+ Expression::DisableElimination | Expression::DisableTypingDeduction);
+ s->appendArgument(argument(np, "error"), CommonSequenceTypes::ZeroOrOneQName);
+ s->appendArgument(argument(np, "description"), CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "errorObject"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::escape_html_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::escape_html_uri, 1, 1, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "uri"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::exactly_one == localName)
+ {
+ s = addFunction(StandardLocalNames::exactly_one, 1, 1, CommonSequenceTypes::ExactlyOneItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ExactlyOneItem);
+ }
+ else if(StandardLocalNames::exists == localName)
+ {
+ s = addFunction(StandardLocalNames::exists, 1, 1, CommonSequenceTypes::ExactlyOneBoolean, Expression::IDExistsFN);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::hours_from_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::hours_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ }
+ else if(StandardLocalNames::hours_from_duration == localName)
+ {
+ s = addFunction(StandardLocalNames::hours_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration);
+ }
+ else if(StandardLocalNames::hours_from_time == localName)
+ {
+ s = addFunction(StandardLocalNames::hours_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime);
+ }
+ else if(StandardLocalNames::idref == localName)
+ {
+ s = addFunction(StandardLocalNames::idref, 1, 2, CommonSequenceTypes::ZeroOrMoreElements,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "idrefs"), CommonSequenceTypes::ZeroOrMoreStrings);
+ s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode);
+ }
+ else if(StandardLocalNames::implicit_timezone == localName)
+ {
+ s = addFunction(StandardLocalNames::implicit_timezone, 0, 0, CommonSequenceTypes::ExactlyOneDayTimeDuration,
+ Expression::DisableElimination);
+ }
+ else if(StandardLocalNames::in_scope_prefixes == localName)
+ {
+ s = addFunction(StandardLocalNames::in_scope_prefixes, 1, 1, CommonSequenceTypes::ZeroOrMoreStrings);
+ s->appendArgument(argument(np, "element"), CommonSequenceTypes::ExactlyOneElement);
+ }
+ else if(StandardLocalNames::index_of == localName)
+ {
+ s = addFunction(StandardLocalNames::index_of, 2, 3, CommonSequenceTypes::ZeroOrMoreIntegers,
+ Expression::LastOperandIsCollation);
+ s->appendArgument(argument(np, "seqParam"), CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ s->appendArgument(argument(np, "searchParam"), CommonSequenceTypes::ExactlyOneAtomicType);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::insert_before == localName)
+ {
+ s = addFunction(StandardLocalNames::insert_before, 3, 3, CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "target"), CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "position"), CommonSequenceTypes::ExactlyOneInteger);
+ s->appendArgument(argument(np, "insert"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::iri_to_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::iri_to_uri, 1, 1, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "uri_part"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::local_name_from_QName == localName)
+ {
+ s = addFunction(StandardLocalNames::local_name_from_QName, 1, 1, CommonSequenceTypes::ZeroOrOneNCName,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneQName);
+ }
+ else if(StandardLocalNames::lower_case == localName)
+ {
+ s = addFunction(StandardLocalNames::lower_case, 1, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::IDLowerCaseFN);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::matches == localName)
+ {
+ s = addFunction(StandardLocalNames::matches, 2, 3, CommonSequenceTypes::ExactlyOneBoolean);
+ s->appendArgument(argument(np, "input"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "pattern"), CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "flags"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::max == localName)
+ {
+ s = addFunction(StandardLocalNames::max, 1, 2, CommonSequenceTypes::ZeroOrOneAtomicType,
+ Expression::LastOperandIsCollation |
+ Expression::EmptynessFollowsChild |
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::min == localName)
+ {
+ s = addFunction(StandardLocalNames::min, 1, 2, CommonSequenceTypes::ZeroOrOneAtomicType,
+ Expression::LastOperandIsCollation |
+ Expression::EmptynessFollowsChild |
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::minutes_from_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::minutes_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ }
+ else if(StandardLocalNames::minutes_from_duration == localName)
+ {
+ s = addFunction(StandardLocalNames::minutes_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration);
+ }
+ else if(StandardLocalNames::minutes_from_time == localName)
+ {
+ s = addFunction(StandardLocalNames::minutes_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime);
+ }
+ else if(StandardLocalNames::month_from_date == localName)
+ {
+ s = addFunction(StandardLocalNames::month_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate);
+ }
+ else if(StandardLocalNames::month_from_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::month_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ }
+ else if(StandardLocalNames::months_from_duration == localName)
+ {
+ s = addFunction(StandardLocalNames::months_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration);
+ }
+ else if(StandardLocalNames::namespace_uri_for_prefix == localName)
+ {
+ s = addFunction(StandardLocalNames::namespace_uri_for_prefix, 2, 2, CommonSequenceTypes::ZeroOrOneAnyURI);
+ s->appendArgument(argument(np, "prefix"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "element"), CommonSequenceTypes::ExactlyOneElement);
+ }
+ else if(StandardLocalNames::namespace_uri_from_QName == localName)
+ {
+ s = addFunction(StandardLocalNames::namespace_uri_from_QName, 1, 1, CommonSequenceTypes::ZeroOrOneAnyURI,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneQName);
+ }
+ else if(StandardLocalNames::nilled == localName)
+ {
+ s = addFunction(StandardLocalNames::nilled, 1, 1, CommonSequenceTypes::ZeroOrOneBoolean);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::node_name == localName)
+ {
+ s = addFunction(StandardLocalNames::node_name, 1, 1, CommonSequenceTypes::ZeroOrOneQName);
+ s->appendArgument(argument(np, "theNode"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::normalize_unicode == localName)
+ {
+ s = addFunction(StandardLocalNames::normalize_unicode, 1, 2, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "normalizationForm"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::one_or_more == localName)
+ {
+ s = addFunction(StandardLocalNames::one_or_more, 1, 1, CommonSequenceTypes::OneOrMoreItems);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::prefix_from_QName == localName)
+ {
+ s = addFunction(StandardLocalNames::prefix_from_QName, 1, 1, CommonSequenceTypes::ZeroOrOneNCName,
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneQName);
+ }
+ else if(StandardLocalNames::remove == localName)
+ {
+ s = addFunction(StandardLocalNames::remove, 2, 2, CommonSequenceTypes::ZeroOrMoreItems,
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "target"), CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "position"), CommonSequenceTypes::ExactlyOneInteger);
+ }
+ else if(StandardLocalNames::replace == localName)
+ {
+ s = addFunction(StandardLocalNames::replace, 3, 4, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "input"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "pattern"), CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "replacement"), CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "flags"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::resolve_QName == localName)
+ {
+ s = addFunction(StandardLocalNames::resolve_QName, 2, 2, CommonSequenceTypes::ZeroOrOneQName,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "qname"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "element"), CommonSequenceTypes::ExactlyOneElement);
+ }
+ else if(StandardLocalNames::resolve_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::resolve_uri, 1, 2, CommonSequenceTypes::ZeroOrOneAnyURI,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "relative"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "base"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::reverse == localName)
+ {
+ s = addFunction(StandardLocalNames::reverse, 1, 1, CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::root == localName)
+ {
+ s = addFunction(StandardLocalNames::root, 0, 1, CommonSequenceTypes::ZeroOrOneNode,
+ Expression::EmptynessFollowsChild |
+ Expression::RewriteToEmptyOnEmpty |
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(StandardLocalNames::round_half_to_even == localName)
+ {
+ s = addFunction(StandardLocalNames::round_half_to_even, 1, 2, CommonSequenceTypes::ZeroOrOneNumeric,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric);
+ s->appendArgument(argument(np, "precision"), CommonSequenceTypes::ExactlyOneInteger);
+ }
+ else if(StandardLocalNames::seconds_from_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::seconds_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneDecimal,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ }
+ else if(StandardLocalNames::seconds_from_duration == localName)
+ {
+ s = addFunction(StandardLocalNames::seconds_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneDecimal,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration);
+ }
+ else if(StandardLocalNames::seconds_from_time == localName)
+ {
+ s = addFunction(StandardLocalNames::seconds_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneDecimal,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime);
+ }
+ else if(StandardLocalNames::static_base_uri == localName)
+ {
+ s = addFunction(StandardLocalNames::static_base_uri, 0, 0, CommonSequenceTypes::ExactlyOneAnyURI, Expression::EmptynessFollowsChild);
+ }
+ else if(StandardLocalNames::string_join == localName)
+ {
+ s = addFunction(StandardLocalNames::string_join, 2, 2, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrMoreStrings);
+ s->appendArgument(argument(np, "separator"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::generic_string_join == localName)
+ {
+ s = addFunction(StandardLocalNames::generic_string_join, 2, 2, CommonSequenceTypes::ExactlyOneString,
+ Expression::IDIgnorableExpression,
+ Expression::Properties(),
+ StandardNamespaces::InternalXSLT);
+ s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ s->appendArgument(argument(np, "separator"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::string_to_codepoints == localName)
+ {
+ s = addFunction(StandardLocalNames::string_to_codepoints, 1, 1, CommonSequenceTypes::ZeroOrMoreIntegers);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::subsequence == localName)
+ {
+ s = addFunction(StandardLocalNames::subsequence, 2, 3, CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "sourceSeq"), CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "startingLoc"), CommonSequenceTypes::ExactlyOneDouble);
+ s->appendArgument(argument(np, "length"), CommonSequenceTypes::ExactlyOneDouble);
+ }
+ else if(StandardLocalNames::timezone_from_date == localName)
+ {
+ s = addFunction(StandardLocalNames::timezone_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneDayTimeDuration,
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate);
+ }
+ else if(StandardLocalNames::timezone_from_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::timezone_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneDayTimeDuration,
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ }
+ else if(StandardLocalNames::timezone_from_time == localName)
+ {
+ s = addFunction(StandardLocalNames::timezone_from_time, 1, 1, CommonSequenceTypes::ZeroOrOneDayTimeDuration,
+ Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneTime);
+ }
+ else if(StandardLocalNames::tokenize == localName)
+ {
+ s = addFunction(StandardLocalNames::tokenize, 2, 3, CommonSequenceTypes::ZeroOrMoreStrings);
+ s->appendArgument(argument(np, "input"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "pattern"), CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "flags"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::trace == localName)
+ {
+ s = addFunction(StandardLocalNames::trace, 2, 2, CommonSequenceTypes::ZeroOrMoreItems,
+ Expression::DisableElimination);
+ s->appendArgument(argument(np, "value"), CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "label"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(StandardLocalNames::unordered == localName)
+ {
+ s = addFunction(StandardLocalNames::unordered, 1, 1, CommonSequenceTypes::ZeroOrMoreItems);
+ s->appendArgument(argument(np, "sourceSeq"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ else if(StandardLocalNames::upper_case == localName)
+ {
+ s = addFunction(StandardLocalNames::upper_case, 1, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::IDUpperCaseFN);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(StandardLocalNames::year_from_date == localName)
+ {
+ s = addFunction(StandardLocalNames::year_from_date, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDate);
+ }
+ else if(StandardLocalNames::year_from_dateTime == localName)
+ {
+ s = addFunction(StandardLocalNames::year_from_dateTime, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDateTime);
+ }
+ else if(StandardLocalNames::years_from_duration == localName)
+ {
+ s = addFunction(StandardLocalNames::years_from_duration, 1, 1, CommonSequenceTypes::ZeroOrOneInteger,
+ Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneDuration);
+ }
+ else if(StandardLocalNames::zero_or_one == localName)
+ {
+ s = addFunction(StandardLocalNames::zero_or_one, 1, 1, CommonSequenceTypes::ZeroOrOneItem);
+ s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems);
+ }
+ }
+
+ return s;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qxpath20corefunctions_p.h b/src/xmlpatterns/functions/qxpath20corefunctions_p.h
new file mode 100644
index 0000000000..fb5bee593b
--- /dev/null
+++ b/src/xmlpatterns/functions/qxpath20corefunctions_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XPath20CoreFunctions_H
+#define Patternist_XPath20CoreFunctions_H
+
+#include "qabstractfunctionfactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Handles the functions defines in XQuery 1.0 and XPath 2.0
+ * Function and Operators, except those also available in XPath 1.0.
+ *
+ * All XPath 2.0 functions is the union of the functions available in XPath20CoreFunctions
+ * and XPath10CoreFunctions. One could therefore say that the name XPath20CoreFunctions is a
+ * bit misleading.
+ *
+ * @see XPath10CoreFunctions
+ * @see <a href ="http://www.w3.org/TR/xpath-functions/">XQuery 1.0
+ * and XPath 2.0 Functions and Operators</a>
+ * @see <a href="http://www.w3.org/TR/xpath.html#corelib">XML Path Language (XPath)
+ * Version 1.0, 4 Core Function Library</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ */
+ class XPath20CoreFunctions : public AbstractFunctionFactory
+ {
+ protected:
+ virtual Expression::Ptr retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const;
+
+ virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np,
+ const QXmlName name);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/functions/qxslt20corefunctions.cpp b/src/xmlpatterns/functions/qxslt20corefunctions.cpp
new file mode 100644
index 0000000000..8e9ee17009
--- /dev/null
+++ b/src/xmlpatterns/functions/qxslt20corefunctions.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcurrentfn_p.h"
+#include "qdocumentfn_p.h"
+#include "qelementavailablefn_p.h"
+#include "qfunctionavailablefn_p.h"
+#include "qgenerateidfn_p.h"
+#include "qsystempropertyfn_p.h"
+#include "qtypeavailablefn_p.h"
+#include "qunparsedentitypublicidfn_p.h"
+#include "qunparsedentityurifn_p.h"
+#include "qunparsedtextavailablefn_p.h"
+#include "qunparsedtextfn_p.h"
+
+#include "qxslt20corefunctions_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr XSLT20CoreFunctions::retrieveExpression(const QXmlName lname,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const
+{
+ Q_ASSERT(sign);
+
+ Expression::Ptr fn;
+#define testXSLTFN(ln, cname) else if(lname.localName() == StandardLocalNames::ln) fn = Expression::Ptr(new cname())
+
+ if(false) /* Dummy for the macro handling. Will be optimized away anyway. */
+ return Expression::Ptr();
+ /* Alphabetic order. */
+ testXSLTFN(current, CurrentFN);
+ testXSLTFN(document, DocumentFN);
+ testXSLTFN(element_available, ElementAvailableFN);
+ testXSLTFN(function_available, FunctionAvailableFN);
+ testXSLTFN(generate_id, GenerateIDFN);
+ testXSLTFN(system_property, SystemPropertyFN);
+ testXSLTFN(type_available, TypeAvailableFN);
+ testXSLTFN(unparsed_entity_public_id, UnparsedEntityPublicIDFN);
+ testXSLTFN(unparsed_entity_uri, UnparsedEntityURIFN);
+ testXSLTFN(unparsed_text_available, UnparsedTextAvailableFN);
+ testXSLTFN(unparsed_text, UnparsedTextFN);
+#undef testXSLTFN
+
+ Q_ASSERT(fn);
+ fn->setOperands(args);
+ fn->as<FunctionCall>()->setSignature(sign);
+
+ return fn;
+}
+
+FunctionSignature::Ptr XSLT20CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name)
+{
+ if(StandardNamespaces::fn != name.namespaceURI())
+ return FunctionSignature::Ptr();
+
+ FunctionSignature::Ptr s(functionSignatures().value(name));
+
+ if(!s)
+ {
+ /* Alphabetic order. */
+ if(name.localName() == StandardLocalNames::element_available)
+ {
+ s = addFunction(StandardLocalNames::element_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean);
+ s->appendArgument(argument(np, "element-name"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(name.localName() == StandardLocalNames::function_available)
+ {
+ s = addFunction(StandardLocalNames::function_available, 1, 2, CommonSequenceTypes::ExactlyOneBoolean);
+ s->appendArgument(argument(np, "function_name"), CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "arity"), CommonSequenceTypes::ExactlyOneInteger);
+ }
+ else if(name.localName() == StandardLocalNames::type_available)
+ {
+ s = addFunction(StandardLocalNames::type_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean);
+ s->appendArgument(argument(np, "type_name"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(name.localName() == StandardLocalNames::system_property)
+ {
+ s = addFunction(StandardLocalNames::system_property, 1, 1, CommonSequenceTypes::ExactlyOneString);
+ s->appendArgument(argument(np, "property_name"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(name.localName() == StandardLocalNames::generate_id)
+ {
+ s = addFunction(StandardLocalNames::generate_id, 0, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::UseContextItem);
+ s->appendArgument(argument(np, "node"), CommonSequenceTypes::ZeroOrOneNode);
+ }
+ else if(name.localName() == StandardLocalNames::unparsed_text)
+ {
+ s = addFunction(StandardLocalNames::unparsed_text, 1, 2, CommonSequenceTypes::ZeroOrOneString,
+ Expression::DisableElimination);
+ s->appendArgument(argument(np, "href"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "encoding"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(name.localName() == StandardLocalNames::unparsed_text_available)
+ {
+ s = addFunction(StandardLocalNames::unparsed_text_available, 1, 2, CommonSequenceTypes::ExactlyOneBoolean,
+ Expression::DisableElimination);
+ s->appendArgument(argument(np, "href"), CommonSequenceTypes::ZeroOrOneString);
+ s->appendArgument(argument(np, "encoding"), CommonSequenceTypes::ZeroOrOneString);
+ }
+ else if(name.localName() == StandardLocalNames::current)
+ {
+ s = addFunction(StandardLocalNames::current, 0, 0, CommonSequenceTypes::ExactlyOneItem,
+ Expression::DisableElimination | Expression::RequiresCurrentItem);
+ }
+ else if(name.localName() == StandardLocalNames::document)
+ {
+ s = addFunction(StandardLocalNames::document, 1, 2, CommonSequenceTypes::OneOrMoreDocumentNodes,
+ Expression::DisableElimination);
+ s->appendArgument(argument(np, "uri-sequence"), CommonSequenceTypes::ZeroOrMoreStrings);
+ s->appendArgument(argument(np, "base-uri-node"), CommonSequenceTypes::ExactlyOneNode);
+ }
+ else if(name.localName() == StandardLocalNames::unparsed_entity_uri)
+ {
+ s = addFunction(StandardLocalNames::unparsed_entity_uri, 1, 1, CommonSequenceTypes::ExactlyOneAnyURI,
+ Expression::RequiresFocus | Expression::DisableElimination);
+ s->appendArgument(argument(np, "entity-name"), CommonSequenceTypes::ExactlyOneString);
+ }
+ else if(name.localName() == StandardLocalNames::unparsed_entity_public_id)
+ {
+ s = addFunction(StandardLocalNames::unparsed_entity_public_id, 1, 1, CommonSequenceTypes::ExactlyOneString,
+ Expression::RequiresFocus | Expression::DisableElimination);
+ s->appendArgument(argument(np, "entity-name"), CommonSequenceTypes::ExactlyOneString);
+ }
+ }
+
+ return s;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/functions/qxslt20corefunctions_p.h b/src/xmlpatterns/functions/qxslt20corefunctions_p.h
new file mode 100644
index 0000000000..bbacf93ca9
--- /dev/null
+++ b/src/xmlpatterns/functions/qxslt20corefunctions_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XSLT20CoreFunctions_H
+#define Patternist_XSLT20CoreFunctions_H
+
+#include "qabstractfunctionfactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Handles the functions defines in XSL-T 2.0, except those also available in XPath 2.0.
+ *
+ * @note XPath20CoreFunctions inherits from XPath10CoreFunctions only for implementation
+ * reasons, it does not supply the functions in the XPath10CoreFunctions factory.
+ *
+ * @see <a href ="http://www.w3.org/TR/xpath-functions/">XQuery 1.0
+ * and XPath 2.0 Functions and Operators</a>
+ * @see <a href="http://www.w3.org/TR/xpath.html#corelib">XML Path Language (XPath)
+ * Version 1.0, 4 Core Function Library</a>
+ * @author Frans Englich <fenglich@trolltech.com>
+ * @ingroup Patternist_functions
+ * @since 4.5
+ */
+ class XSLT20CoreFunctions : public AbstractFunctionFactory
+ {
+ protected:
+ virtual Expression::Ptr retrieveExpression(const QXmlName name,
+ const Expression::List &args,
+ const FunctionSignature::Ptr &sign) const;
+
+ virtual FunctionSignature::Ptr retrieveFunctionSignature(const NamePool::Ptr &np,
+ const QXmlName name);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/iterators/iterators.pri b/src/xmlpatterns/iterators/iterators.pri
new file mode 100644
index 0000000000..3850334057
--- /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 0000000000..a1f6adeafd
--- /dev/null
+++ b/src/xmlpatterns/iterators/qcachingiterator.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+#include "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 0000000000..ebf5fda6a1
--- /dev/null
+++ b/src/xmlpatterns/iterators/qcachingiterator_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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.fenglich@trolltech.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 0000000000..43088d59dc
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdeduplicateiterator.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..07881c5aa3
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdeduplicateiterator_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..43951eaa9b
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdistinctiterator.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "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 0000000000..86fbd79327
--- /dev/null
+++ b/src/xmlpatterns/iterators/qdistinctiterator_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..310512ec88
--- /dev/null
+++ b/src/xmlpatterns/iterators/qemptyiterator_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..68609f7d35
--- /dev/null
+++ b/src/xmlpatterns/iterators/qexceptiterator.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..7528ef6641
--- /dev/null
+++ b/src/xmlpatterns/iterators/qexceptiterator_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 0000000000..df7edebfe6
--- /dev/null
+++ b/src/xmlpatterns/iterators/qindexofiterator.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..62594f94ee
--- /dev/null
+++ b/src/xmlpatterns/iterators/qindexofiterator_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..7d4eb986be
--- /dev/null
+++ b/src/xmlpatterns/iterators/qinsertioniterator.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "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 0000000000..4d89c268d1
--- /dev/null
+++ b/src/xmlpatterns/iterators/qinsertioniterator_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..3073810c6b
--- /dev/null
+++ b/src/xmlpatterns/iterators/qintersectiterator.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..c8ada57417
--- /dev/null
+++ b/src/xmlpatterns/iterators/qintersectiterator_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..284296cb01
--- /dev/null
+++ b/src/xmlpatterns/iterators/qitemmappingiterator_p.h
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..7f8f6296d6
--- /dev/null
+++ b/src/xmlpatterns/iterators/qrangeiterator.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..0a0f29414b
--- /dev/null
+++ b/src/xmlpatterns/iterators/qrangeiterator_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..eb27ce7938
--- /dev/null
+++ b/src/xmlpatterns/iterators/qremovaliterator.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "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 0000000000..e5f8ad305b
--- /dev/null
+++ b/src/xmlpatterns/iterators/qremovaliterator_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..2e203fb218
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsequencemappingiterator_p.h
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d37f0575ce
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsingletoniterator_p.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..4d9ee96611
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsubsequenceiterator.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..1217069bdb
--- /dev/null
+++ b/src/xmlpatterns/iterators/qsubsequenceiterator_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..63d92ab10c
--- /dev/null
+++ b/src/xmlpatterns/iterators/qtocodepointsiterator.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..2c9f48189b
--- /dev/null
+++ b/src/xmlpatterns/iterators/qtocodepointsiterator_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..7a54a0d40c
--- /dev/null
+++ b/src/xmlpatterns/iterators/qunioniterator.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..6db0889b56
--- /dev/null
+++ b/src/xmlpatterns/iterators/qunioniterator_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..25de3a4527
--- /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 0000000000..f067089e28
--- /dev/null
+++ b/src/xmlpatterns/janitors/qargumentconverter.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..aa89d950a3
--- /dev/null
+++ b/src/xmlpatterns/janitors/qargumentconverter_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..929f22db93
--- /dev/null
+++ b/src/xmlpatterns/janitors/qatomizer.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..a1b7dfa132
--- /dev/null
+++ b/src/xmlpatterns/janitors/qatomizer_p.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0d51d2c9bd
--- /dev/null
+++ b/src/xmlpatterns/janitors/qcardinalityverifier.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "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 0000000000..c51f1e1106
--- /dev/null
+++ b/src/xmlpatterns/janitors/qcardinalityverifier_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..8ed3068d3e
--- /dev/null
+++ b/src/xmlpatterns/janitors/qebvextractor.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "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 0000000000..443560b337
--- /dev/null
+++ b/src/xmlpatterns/janitors/qebvextractor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..cf88cee1fe
--- /dev/null
+++ b/src/xmlpatterns/janitors/qitemverifier.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..3da9ad990f
--- /dev/null
+++ b/src/xmlpatterns/janitors/qitemverifier_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..937a8f9d1e
--- /dev/null
+++ b/src/xmlpatterns/janitors/quntypedatomicconverter.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..0d475b4bb6
--- /dev/null
+++ b/src/xmlpatterns/janitors/quntypedatomicconverter_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..61b39a87ec
--- /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 0000000000..615637a31d
--- /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 0000000000..e55007ed88
--- /dev/null
+++ b/src/xmlpatterns/parser/TokenLookup.gperf
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file 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 <fenglich@trolltech.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 0000000000..51453eeaf5
--- /dev/null
+++ b/src/xmlpatterns/parser/createParser.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+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 0000000000..a4e1effb3d
--- /dev/null
+++ b/src/xmlpatterns/parser/createTokenLookup.sh
@@ -0,0 +1,5 @@
+outFile="qtokenlookup.cpp"
+
+# 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 0000000000..3a60dc4eff
--- /dev/null
+++ b/src/xmlpatterns/parser/createXSLTTokenLookup.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+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 0000000000..6656290fe8
--- /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 0000000000..0ac0804323
--- /dev/null
+++ b/src/xmlpatterns/parser/qmaintainingreader.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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))
+ {
+ const ElementDescription<TokenLookupClass, LookupKey> &desc = m_elementDescriptions.value(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(formatKeyword(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(formatKeyword(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 0000000000..2fab61fc3b
--- /dev/null
+++ b/src/xmlpatterns/parser/qmaintainingreader_p.h
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_MaintainingReader_H
+#define Patternist_MaintainingReader_H
+
+#include <QSet>
+#include <QSourceLocation>
+#include <QStack>
+#include <QStringList>
+#include <QXmlStreamReader>
+
+#include "qxpathhelper_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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..7c48deec7f
--- /dev/null
+++ b/src/xmlpatterns/parser/qparsercontext.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..941b6d3ed9
--- /dev/null
+++ b/src/xmlpatterns/parser/qparsercontext_p.h
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..60e3a0ccdf
--- /dev/null
+++ b/src/xmlpatterns/parser/qquerytransformparser.cpp
@@ -0,0 +1,7976 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+/* 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"
+
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#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);
+}
+
+/**
+ * @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, 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 which is
+ * unavailable in XPath.
+ *
+ * If @p isInternal is @c true, no error is raised. Otherwise, if the current
+ * language is not XQuery, an error is raised.
+ */
+static void disallowedConstruct(const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const bool isInternal = false)
+{
+ if(!isInternal && parseInfo->languageAccent != QXmlQuery::XQuery10)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered which only is allowed in XQuery."),
+ 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 by 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 1289 "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, 1341, 1341, 1342, 1344, 1345, 1376, 1377, 1393, 1491,
+ 1493, 1499, 1501, 1508, 1514, 1520, 1527, 1530, 1534, 1538,
+ 1558, 1572, 1576, 1570, 1639, 1643, 1660, 1663, 1665, 1670,
+ 1671, 1675, 1676, 1680, 1684, 1688, 1690, 1691, 1693, 1695,
+ 1741, 1755, 1760, 1765, 1766, 1768, 1783, 1798, 1808, 1823,
+ 1827, 1832, 1846, 1850, 1855, 1869, 1874, 1879, 1884, 1889,
+ 1905, 1928, 1936, 1937, 1938, 1940, 1957, 1958, 1960, 1961,
+ 1963, 1964, 1966, 2021, 2025, 2031, 2034, 2039, 2053, 2057,
+ 2063, 2062, 2171, 2174, 2180, 2201, 2207, 2211, 2213, 2218,
+ 2228, 2229, 2234, 2235, 2244, 2314, 2325, 2326, 2330, 2335,
+ 2404, 2405, 2409, 2414, 2458, 2459, 2464, 2471, 2477, 2478,
+ 2479, 2480, 2481, 2482, 2488, 2493, 2499, 2502, 2507, 2513,
+ 2519, 2523, 2548, 2549, 2553, 2557, 2551, 2598, 2601, 2596,
+ 2617, 2618, 2619, 2622, 2626, 2634, 2633, 2647, 2646, 2655,
+ 2656, 2657, 2659, 2667, 2678, 2681, 2683, 2688, 2695, 2702,
+ 2708, 2728, 2733, 2739, 2742, 2744, 2745, 2752, 2758, 2762,
+ 2767, 2768, 2771, 2775, 2770, 2784, 2788, 2783, 2796, 2799,
+ 2803, 2798, 2812, 2816, 2811, 2824, 2826, 2854, 2853, 2865,
+ 2873, 2864, 2884, 2885, 2888, 2892, 2897, 2902, 2901, 2917,
+ 2922, 2923, 2928, 2929, 2934, 2935, 2936, 2937, 2939, 2940,
+ 2945, 2946, 2951, 2952, 2954, 2955, 2960, 2961, 2962, 2963,
+ 2965, 2966, 2971, 2972, 2977, 2978, 2980, 2984, 2989, 2990,
+ 2996, 2997, 3002, 3003, 3008, 3009, 3014, 3015, 3020, 3024,
+ 3029, 3030, 3031, 3033, 3038, 3039, 3040, 3041, 3042, 3043,
+ 3045, 3050, 3051, 3052, 3053, 3054, 3055, 3057, 3062, 3063,
+ 3064, 3066, 3080, 3081, 3082, 3084, 3100, 3104, 3109, 3110,
+ 3112, 3117, 3118, 3120, 3126, 3130, 3136, 3139, 3140, 3144,
+ 3153, 3158, 3162, 3163, 3168, 3167, 3182, 3189, 3188, 3203,
+ 3211, 3211, 3220, 3222, 3225, 3230, 3232, 3236, 3302, 3305,
+ 3311, 3314, 3323, 3327, 3331, 3336, 3337, 3342, 3343, 3346,
+ 3345, 3375, 3377, 3378, 3380, 3394, 3395, 3396, 3397, 3398,
+ 3399, 3400, 3401, 3402, 3403, 3404, 3405, 3408, 3407, 3417,
+ 3428, 3433, 3435, 3440, 3441, 3443, 3447, 3449, 3453, 3462,
+ 3468, 3469, 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481,
+ 3491, 3492, 3497, 3501, 3506, 3511, 3516, 3521, 3525, 3530,
+ 3535, 3540, 3569, 3573, 3580, 3582, 3586, 3588, 3589, 3590,
+ 3624, 3633, 3622, 3874, 3878, 3898, 3901, 3907, 3912, 3917,
+ 3923, 3926, 3936, 3943, 3947, 3953, 3967, 3973, 3990, 3995,
+ 4008, 4009, 4010, 4011, 4012, 4013, 4014, 4016, 4024, 4023,
+ 4063, 4066, 4071, 4086, 4091, 4098, 4110, 4114, 4110, 4120,
+ 4122, 4126, 4128, 4143, 4147, 4156, 4161, 4165, 4171, 4174,
+ 4179, 4184, 4189, 4190, 4191, 4192, 4194, 4195, 4196, 4197,
+ 4202, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4246, 4251,
+ 4256, 4262, 4263, 4265, 4270, 4275, 4280, 4285, 4301, 4302,
+ 4304, 4309, 4314, 4318, 4330, 4343, 4353, 4358, 4363, 4368,
+ 4382, 4396, 4397, 4399, 4409, 4411, 4416, 4423, 4430, 4432,
+ 4434, 4435, 4437, 4441, 4446, 4447, 4449, 4455, 4457, 4459,
+ 4460, 4462, 4474
+};
+#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 1346 "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 1378 "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 1394 "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 1494 "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 1502 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 1509 "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 1515 "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 1521 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 1531 "querytransformparser.ypp"
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 18:
+/* Line 1269 of yacc.c. */
+#line 1535 "querytransformparser.ypp"
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 19:
+/* Line 1269 of yacc.c. */
+#line 1539 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 20:
+/* Line 1269 of yacc.c. */
+#line 1562 "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 1572 "querytransformparser.ypp"
+ {
+ parseInfo->isParsingPattern = true;
+ }
+ break;
+
+ case 22:
+/* Line 1269 of yacc.c. */
+#line 1576 "querytransformparser.ypp"
+ {
+ parseInfo->isParsingPattern = false;
+ }
+ break;
+
+ case 23:
+/* Line 1269 of yacc.c. */
+#line 1585 "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 1639 "querytransformparser.ypp"
+ {
+ (yyval.enums.Double) = std::numeric_limits<xsDouble>::quiet_NaN();
+ }
+ break;
+
+ case 25:
+/* Line 1269 of yacc.c. */
+#line 1644 "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 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 1660 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName();
+ }
+ break;
+
+ case 28:
+/* Line 1269 of yacc.c. */
+#line 1666 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (2)].qName);
+ }
+ break;
+
+ case 30:
+/* Line 1269 of yacc.c. */
+#line 1672 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ }
+ break;
+
+ case 32:
+/* Line 1269 of yacc.c. */
+#line 1677 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ }
+ break;
+
+ case 33:
+/* Line 1269 of yacc.c. */
+#line 1681 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ }
+ break;
+
+ case 34:
+/* Line 1269 of yacc.c. */
+#line 1685 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ }
+ break;
+
+ case 39:
+/* Line 1269 of yacc.c. */
+#line 1696 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(6) - (7)].enums.Bool))
+ disallowedConstruct(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 can not 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 1742 "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 1756 "querytransformparser.ypp"
+ {
+ (yyval.enums.boundarySpacePolicy) = StaticContext::BSPStrip;
+ }
+ break;
+
+ case 42:
+/* Line 1269 of yacc.c. */
+#line 1761 "querytransformparser.ypp"
+ {
+ (yyval.enums.boundarySpacePolicy) = StaticContext::BSPPreserve;
+ }
+ break;
+
+ case 45:
+/* Line 1269 of yacc.c. */
+#line 1770 "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 1785 "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 1799 "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 1809 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 1824 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingMode) = StaticContext::Ordered;
+ }
+ break;
+
+ case 50:
+/* Line 1269 of yacc.c. */
+#line 1828 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingMode) = StaticContext::Unordered;
+ }
+ break;
+
+ case 51:
+/* Line 1269 of yacc.c. */
+#line 1833 "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 1847 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = StaticContext::Least;
+ }
+ break;
+
+ case 53:
+/* Line 1269 of yacc.c. */
+#line 1851 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = StaticContext::Greatest;
+ }
+ break;
+
+ case 54:
+/* Line 1269 of yacc.c. */
+#line 1857 "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 1870 "querytransformparser.ypp"
+ {
+ parseInfo->preserveNamespacesMode = true;
+ }
+ break;
+
+ case 56:
+/* Line 1269 of yacc.c. */
+#line 1875 "querytransformparser.ypp"
+ {
+ parseInfo->preserveNamespacesMode = false;
+ }
+ break;
+
+ case 57:
+/* Line 1269 of yacc.c. */
+#line 1880 "querytransformparser.ypp"
+ {
+ parseInfo->inheritNamespacesMode = true;
+ }
+ break;
+
+ case 58:
+/* Line 1269 of yacc.c. */
+#line 1885 "querytransformparser.ypp"
+ {
+ parseInfo->inheritNamespacesMode = false;
+ }
+ break;
+
+ case 59:
+/* Line 1269 of yacc.c. */
+#line 1890 "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 1906 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 1929 "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 1941 "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 1968 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc), (yyvsp[(3) - (9)].enums.Bool));
+ if(variableByName((yyvsp[(5) - (9)].qName), parseInfo))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by 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 by 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 2022 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 74:
+/* Line 1269 of yacc.c. */
+#line 2026 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 75:
+/* Line 1269 of yacc.c. */
+#line 2031 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 76:
+/* Line 1269 of yacc.c. */
+#line 2035 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 77:
+/* Line 1269 of yacc.c. */
+#line 2040 "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 2054 "querytransformparser.ypp"
+ {
+ (yyval.enums.constructionMode) = StaticContext::CMStrip;
+ }
+ break;
+
+ case 79:
+/* Line 1269 of yacc.c. */
+#line 2058 "querytransformparser.ypp"
+ {
+ (yyval.enums.constructionMode) = StaticContext::CMPreserve;
+ }
+ break;
+
+ case 80:
+/* Line 1269 of yacc.c. */
+#line 2063 "querytransformparser.ypp"
+ {
+ (yyval.enums.slot) = parseInfo->currentExpressionSlot() - (yyvsp[(6) - (7)].functionArguments).count();
+ }
+ break;
+
+ case 81:
+/* Line 1269 of yacc.c. */
+#line 2067 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(3) - (11)].enums.Bool))
+ disallowedConstruct(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 2171 "querytransformparser.ypp"
+ {
+ (yyval.functionArguments) = FunctionArgument::List();
+ }
+ break;
+
+ case 83:
+/* Line 1269 of yacc.c. */
+#line 2175 "querytransformparser.ypp"
+ {
+ FunctionArgument::List l;
+ l.append((yyvsp[(1) - (1)].functionArgument));
+ (yyval.functionArguments) = l;
+ }
+ break;
+
+ case 84:
+/* Line 1269 of yacc.c. */
+#line 2181 "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 by 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 2202 "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 2208 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 88:
+/* Line 1269 of yacc.c. */
+#line 2214 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 91:
+/* Line 1269 of yacc.c. */
+#line 2230 "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 2236 "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 2245 "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 2315 "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 2327 "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 2331 "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 2336 "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 2406 "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 2410 "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 2415 "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 2460 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ExpressionSequence((yyvsp[(1) - (1)].expressionList)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 106:
+/* Line 1269 of yacc.c. */
+#line 2465 "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 2472 "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 2483 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(3) - (4)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 114:
+/* Line 1269 of yacc.c. */
+#line 2488 "querytransformparser.ypp"
+ {
+ QVector<QXmlName> result;
+ result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
+ (yyval.qNameVector) = result;
+ }
+ break;
+
+ case 115:
+/* Line 1269 of yacc.c. */
+#line 2494 "querytransformparser.ypp"
+ {
+ (yyval.qNameVector) = (yyvsp[(2) - (2)].qNameVector);
+ }
+ break;
+
+ case 116:
+/* Line 1269 of yacc.c. */
+#line 2499 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ }
+ break;
+
+ case 117:
+/* Line 1269 of yacc.c. */
+#line 2503 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (2)].qName);
+ }
+ break;
+
+ case 118:
+/* Line 1269 of yacc.c. */
+#line 2508 "querytransformparser.ypp"
+ {
+ QVector<QXmlName> result;
+ result.append((yyvsp[(1) - (1)].qName));
+ (yyval.qNameVector) = result;
+ }
+ break;
+
+ case 119:
+/* Line 1269 of yacc.c. */
+#line 2514 "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 2520 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(1) - (1)].qName);
+ }
+ break;
+
+ case 121:
+/* Line 1269 of yacc.c. */
+#line 2524 "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 2553 "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 2557 "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 2564 "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 2598 "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 2601 "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 2608 "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 2622 "querytransformparser.ypp"
+ {
+ (yyval.enums.slot) = -1;
+ }
+ break;
+
+ case 134:
+/* Line 1269 of yacc.c. */
+#line 2627 "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 2634 "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 2638 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 2647 "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 2649 "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 2660 "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 2668 "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 2678 "querytransformparser.ypp"
+ {
+ (yyval.orderSpecs) = OrderSpecTransfer::List();
+ }
+ break;
+
+ case 146:
+/* Line 1269 of yacc.c. */
+#line 2684 "querytransformparser.ypp"
+ {
+ (yyval.orderSpecs) = (yyvsp[(2) - (2)].orderSpecs);
+ }
+ break;
+
+ case 147:
+/* Line 1269 of yacc.c. */
+#line 2689 "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 2696 "querytransformparser.ypp"
+ {
+ OrderSpecTransfer::List list;
+ list.append((yyvsp[(1) - (1)].orderSpec));
+ (yyval.orderSpecs) = list;
+ }
+ break;
+
+ case 149:
+/* Line 1269 of yacc.c. */
+#line 2703 "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 2708 "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 2729 "querytransformparser.ypp"
+ {
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Ascending;
+ }
+ break;
+
+ case 152:
+/* Line 1269 of yacc.c. */
+#line 2734 "querytransformparser.ypp"
+ {
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Descending;
+ }
+ break;
+
+ case 153:
+/* Line 1269 of yacc.c. */
+#line 2739 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = parseInfo->staticContext->orderingEmptySequence();
+ }
+ break;
+
+ case 156:
+/* Line 1269 of yacc.c. */
+#line 2746 "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 2753 "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 2759 "querytransformparser.ypp"
+ {
+ parseInfo->orderStability.push(OrderBy::StableOrder);
+ }
+ break;
+
+ case 159:
+/* Line 1269 of yacc.c. */
+#line 2763 "querytransformparser.ypp"
+ {
+ parseInfo->orderStability.push(OrderBy::UnstableOrder);
+ }
+ break;
+
+ case 162:
+/* Line 1269 of yacc.c. */
+#line 2771 "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 2775 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 164:
+/* Line 1269 of yacc.c. */
+#line 2777 "querytransformparser.ypp"
+ {
+ (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 2784 "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 2788 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 167:
+/* Line 1269 of yacc.c. */
+#line 2790 "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 2799 "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 2803 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 171:
+/* Line 1269 of yacc.c. */
+#line 2805 "querytransformparser.ypp"
+ {
+ (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 2812 "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 2816 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 174:
+/* Line 1269 of yacc.c. */
+#line 2818 "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 2827 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 177:
+/* Line 1269 of yacc.c. */
+#line 2854 "querytransformparser.ypp"
+ {
+ parseInfo->typeswitchSource.push((yyvsp[(3) - (4)].expr));
+ }
+ break;
+
+ case 178:
+/* Line 1269 of yacc.c. */
+#line 2858 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ parseInfo->typeswitchSource.pop();
+ (yyval.expr) = (yyvsp[(6) - (6)].expr);
+ }
+ break;
+
+ case 179:
+/* Line 1269 of yacc.c. */
+#line 2865 "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 2873 "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 2879 "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 2888 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName();
+ }
+ break;
+
+ case 185:
+/* Line 1269 of yacc.c. */
+#line 2893 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (3)].qName);
+ }
+ break;
+
+ case 186:
+/* Line 1269 of yacc.c. */
+#line 2898 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(3) - (3)].expr);
+ }
+ break;
+
+ case 187:
+/* Line 1269 of yacc.c. */
+#line 2902 "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 2911 "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 2918 "querytransformparser.ypp"
+ {
+ (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 2924 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new OrExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 193:
+/* Line 1269 of yacc.c. */
+#line 2930 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AndExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 199:
+/* Line 1269 of yacc.c. */
+#line 2941 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new RangeExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 201:
+/* Line 1269 of yacc.c. */
+#line 2947 "querytransformparser.ypp"
+ {
+ (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 2951 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Add;}
+ break;
+
+ case 203:
+/* Line 1269 of yacc.c. */
+#line 2952 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Substract;}
+ break;
+
+ case 205:
+/* Line 1269 of yacc.c. */
+#line 2956 "querytransformparser.ypp"
+ {
+ (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 2960 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Multiply;}
+ break;
+
+ case 207:
+/* Line 1269 of yacc.c. */
+#line 2961 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Div;}
+ break;
+
+ case 208:
+/* Line 1269 of yacc.c. */
+#line 2962 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::IDiv;}
+ break;
+
+ case 209:
+/* Line 1269 of yacc.c. */
+#line 2963 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Mod;}
+ break;
+
+ case 211:
+/* Line 1269 of yacc.c. */
+#line 2967 "querytransformparser.ypp"
+ {
+ (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 2973 "querytransformparser.ypp"
+ {
+ (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 2981 "querytransformparser.ypp"
+ {
+ (yyval.enums.combinedNodeOp) = CombineNodes::Intersect;
+ }
+ break;
+
+ case 217:
+/* Line 1269 of yacc.c. */
+#line 2985 "querytransformparser.ypp"
+ {
+ (yyval.enums.combinedNodeOp) = CombineNodes::Except;
+ }
+ break;
+
+ case 219:
+/* Line 1269 of yacc.c. */
+#line 2991 "querytransformparser.ypp"
+ {
+ (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 2998 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new TreatAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 223:
+/* Line 1269 of yacc.c. */
+#line 3004 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CastableAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 225:
+/* Line 1269 of yacc.c. */
+#line 3010 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CastAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 227:
+/* Line 1269 of yacc.c. */
+#line 3016 "querytransformparser.ypp"
+ {
+ (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 3021 "querytransformparser.ypp"
+ {
+ (yyval.enums.mathOperator) = AtomicMathematician::Add;
+ }
+ break;
+
+ case 229:
+/* Line 1269 of yacc.c. */
+#line 3025 "querytransformparser.ypp"
+ {
+ (yyval.enums.mathOperator) = AtomicMathematician::Substract;
+ }
+ break;
+
+ case 233:
+/* Line 1269 of yacc.c. */
+#line 3034 "querytransformparser.ypp"
+ {
+ (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 3038 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;}
+ break;
+
+ case 235:
+/* Line 1269 of yacc.c. */
+#line 3039 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;}
+ break;
+
+ case 236:
+/* Line 1269 of yacc.c. */
+#line 3040 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;}
+ break;
+
+ case 237:
+/* Line 1269 of yacc.c. */
+#line 3041 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;}
+ break;
+
+ case 238:
+/* Line 1269 of yacc.c. */
+#line 3042 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;}
+ break;
+
+ case 239:
+/* Line 1269 of yacc.c. */
+#line 3043 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;}
+ break;
+
+ case 240:
+/* Line 1269 of yacc.c. */
+#line 3046 "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 3050 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;}
+ break;
+
+ case 242:
+/* Line 1269 of yacc.c. */
+#line 3051 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;}
+ break;
+
+ case 243:
+/* Line 1269 of yacc.c. */
+#line 3052 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;}
+ break;
+
+ case 244:
+/* Line 1269 of yacc.c. */
+#line 3053 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;}
+ break;
+
+ case 245:
+/* Line 1269 of yacc.c. */
+#line 3054 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;}
+ break;
+
+ case 246:
+/* Line 1269 of yacc.c. */
+#line 3055 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;}
+ break;
+
+ case 247:
+/* Line 1269 of yacc.c. */
+#line 3058 "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 3062 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Is;}
+ break;
+
+ case 249:
+/* Line 1269 of yacc.c. */
+#line 3063 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Precedes;}
+ break;
+
+ case 250:
+/* Line 1269 of yacc.c. */
+#line 3064 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Follows;}
+ break;
+
+ case 251:
+/* Line 1269 of yacc.c. */
+#line 3067 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 3080 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Strict;}
+ break;
+
+ case 253:
+/* Line 1269 of yacc.c. */
+#line 3081 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Strict;}
+ break;
+
+ case 254:
+/* Line 1269 of yacc.c. */
+#line 3082 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Lax;}
+ break;
+
+ case 255:
+/* Line 1269 of yacc.c. */
+#line 3085 "querytransformparser.ypp"
+ {
+ /* 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 3101 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 257:
+/* Line 1269 of yacc.c. */
+#line 3105 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 260:
+/* Line 1269 of yacc.c. */
+#line 3113 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ }
+ break;
+
+ case 263:
+/* Line 1269 of yacc.c. */
+#line 3121 "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 3127 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createSlashSlashPath(createRootExpression(parseInfo, (yyloc)), (yyvsp[(2) - (2)].expr), (yyloc), parseInfo);
+ }
+ break;
+
+ case 265:
+/* Line 1269 of yacc.c. */
+#line 3131 "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 3141 "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 3145 "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 3154 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createSlashSlashPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), (yyloc), parseInfo);
+ }
+ break;
+
+ case 271:
+/* Line 1269 of yacc.c. */
+#line 3159 "querytransformparser.ypp"
+ {
+ (yyval.expr) = NodeSortExpression::wrapAround((yyvsp[(1) - (1)].expr), parseInfo->staticContext);
+ }
+ break;
+
+ case 273:
+/* Line 1269 of yacc.c. */
+#line 3164 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CurrentItemStore((yyvsp[(2) - (2)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 274:
+/* Line 1269 of yacc.c. */
+#line 3168 "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 3176 "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 3183 "querytransformparser.ypp"
+ {
+ 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 3189 "querytransformparser.ypp"
+ {
+ 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 3199 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ (yyval.expr) = (yyvsp[(8) - (9)].expr);
+ }
+ break;
+
+ case 279:
+/* Line 1269 of yacc.c. */
+#line 3204 "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 3211 "querytransformparser.ypp"
+ {
+ parseInfo->startParsingWithParam();
+ }
+ break;
+
+ case 281:
+/* Line 1269 of yacc.c. */
+#line 3215 "querytransformparser.ypp"
+ {
+ parseInfo->endParsingWithParam();
+ }
+ break;
+
+ case 282:
+/* Line 1269 of yacc.c. */
+#line 3220 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 283:
+/* Line 1269 of yacc.c. */
+#line 3223 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 284:
+/* Line 1269 of yacc.c. */
+#line 3226 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 285:
+/* Line 1269 of yacc.c. */
+#line 3230 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 286:
+/* Line 1269 of yacc.c. */
+#line 3233 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 287:
+/* Line 1269 of yacc.c. */
+#line 3237 "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 3302 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = false;
+ }
+ break;
+
+ case 289:
+/* Line 1269 of yacc.c. */
+#line 3306 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = true;
+ }
+ break;
+
+ case 290:
+/* Line 1269 of yacc.c. */
+#line 3311 "querytransformparser.ypp"
+ {
+ (yyval.expr) = Expression::Ptr();
+ }
+ break;
+
+ case 291:
+/* Line 1269 of yacc.c. */
+#line 3315 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 292:
+/* Line 1269 of yacc.c. */
+#line 3324 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::RegularPath;
+ }
+ break;
+
+ case 293:
+/* Line 1269 of yacc.c. */
+#line 3328 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::XSLTForEach;
+ }
+ break;
+
+ case 294:
+/* Line 1269 of yacc.c. */
+#line 3332 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::ForApplyTemplate;
+ }
+ break;
+
+ case 296:
+/* Line 1269 of yacc.c. */
+#line 3338 "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 3346 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (1)].enums.axis) == QXmlNodeModelIndex::AxisAttribute)
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 300:
+/* Line 1269 of yacc.c. */
+#line 3351 "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 3381 "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);
+ }
+ break;
+
+ case 305:
+/* Line 1269 of yacc.c. */
+#line 3394 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestorOrSelf ;}
+ break;
+
+ case 306:
+/* Line 1269 of yacc.c. */
+#line 3395 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestor ;}
+ break;
+
+ case 307:
+/* Line 1269 of yacc.c. */
+#line 3396 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAttribute ;}
+ break;
+
+ case 308:
+/* Line 1269 of yacc.c. */
+#line 3397 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisChild ;}
+ break;
+
+ case 309:
+/* Line 1269 of yacc.c. */
+#line 3398 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendantOrSelf;}
+ break;
+
+ case 310:
+/* Line 1269 of yacc.c. */
+#line 3399 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendant ;}
+ break;
+
+ case 311:
+/* Line 1269 of yacc.c. */
+#line 3400 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowing ;}
+ break;
+
+ case 312:
+/* Line 1269 of yacc.c. */
+#line 3401 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPreceding ;}
+ break;
+
+ case 313:
+/* Line 1269 of yacc.c. */
+#line 3402 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowingSibling;}
+ break;
+
+ case 314:
+/* Line 1269 of yacc.c. */
+#line 3403 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPrecedingSibling;}
+ break;
+
+ case 315:
+/* Line 1269 of yacc.c. */
+#line 3404 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisParent ;}
+ break;
+
+ case 316:
+/* Line 1269 of yacc.c. */
+#line 3405 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisSelf ;}
+ break;
+
+ case 317:
+/* Line 1269 of yacc.c. */
+#line 3408 "querytransformparser.ypp"
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 318:
+/* Line 1269 of yacc.c. */
+#line 3412 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(3) - (3)].itemType)), (yyloc), parseInfo);
+
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 319:
+/* Line 1269 of yacc.c. */
+#line 3418 "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 3429 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(1) - (1)].itemType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 322:
+/* Line 1269 of yacc.c. */
+#line 3436 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), (yyloc), parseInfo);
+ }
+ break;
+
+ case 325:
+/* Line 1269 of yacc.c. */
+#line 3444 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(parseInfo->nodeTestSource, (yyvsp[(1) - (1)].qName));
+ }
+ break;
+
+ case 327:
+/* Line 1269 of yacc.c. */
+#line 3450 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = parseInfo->nodeTestSource;
+ }
+ break;
+
+ case 328:
+/* Line 1269 of yacc.c. */
+#line 3454 "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 3463 "querytransformparser.ypp"
+ {
+ 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 3470 "querytransformparser.ypp"
+ {
+ (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 3482 "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 3493 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Literal(AtomicString::fromValue((yyvsp[(1) - (1)].sval))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 342:
+/* Line 1269 of yacc.c. */
+#line 3498 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createNumericLiteral<Double>((yyvsp[(1) - (1)].sval), (yyloc), parseInfo);
+ }
+ break;
+
+ case 343:
+/* Line 1269 of yacc.c. */
+#line 3502 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createNumericLiteral<Numeric>((yyvsp[(1) - (1)].sval), (yyloc), parseInfo);
+ }
+ break;
+
+ case 344:
+/* Line 1269 of yacc.c. */
+#line 3507 "querytransformparser.ypp"
+ {
+ (yyval.expr) = resolveVariable((yyvsp[(2) - (2)].qName), (yyloc), parseInfo, false);
+ }
+ break;
+
+ case 345:
+/* Line 1269 of yacc.c. */
+#line 3512 "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 3517 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(1) - (1)].qName);
+ }
+ break;
+
+ case 347:
+/* Line 1269 of yacc.c. */
+#line 3522 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 348:
+/* Line 1269 of yacc.c. */
+#line 3526 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new EmptySequence, (yyloc), parseInfo);
+ }
+ break;
+
+ case 349:
+/* Line 1269 of yacc.c. */
+#line 3531 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ContextItem(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 350:
+/* Line 1269 of yacc.c. */
+#line 3536 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 351:
+/* Line 1269 of yacc.c. */
+#line 3541 "querytransformparser.ypp"
+ {
+ 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 by 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 3569 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ }
+ break;
+
+ case 353:
+/* Line 1269 of yacc.c. */
+#line 3574 "querytransformparser.ypp"
+ {
+ Expression::List list;
+ list.append((yyvsp[(1) - (1)].expr));
+ (yyval.expressionList) = list;
+ }
+ break;
+
+ case 355:
+/* Line 1269 of yacc.c. */
+#line 3583 "querytransformparser.ypp"
+ {
+ disallowedConstruct(parseInfo, (yyloc));
+ }
+ break;
+
+ case 360:
+/* Line 1269 of yacc.c. */
+#line 3624 "querytransformparser.ypp"
+ {
+ (yyval.enums.tokenizerPosition) = parseInfo->tokenizer->commenceScanOnly();
+ parseInfo->scanOnlyStack.push(true);
+ }
+ break;
+
+ case 361:
+/* Line 1269 of yacc.c. */
+#line 3633 "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 3779 "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 by 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 3875 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new EmptySequence(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 364:
+/* Line 1269 of yacc.c. */
+#line 3879 "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 3898 "querytransformparser.ypp"
+ {
+ (yyval.attributeHolders) = AttributeHolderVector();
+ }
+ break;
+
+ case 366:
+/* Line 1269 of yacc.c. */
+#line 3902 "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 3908 "querytransformparser.ypp"
+ {
+ (yyval.attributeHolder) = qMakePair((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr));
+ }
+ break;
+
+ case 368:
+/* Line 1269 of yacc.c. */
+#line 3913 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 369:
+/* Line 1269 of yacc.c. */
+#line 3918 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 370:
+/* Line 1269 of yacc.c. */
+#line 3923 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ }
+ break;
+
+ case 371:
+/* Line 1269 of yacc.c. */
+#line 3927 "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 3937 "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 3943 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ break;
+
+ case 374:
+/* Line 1269 of yacc.c. */
+#line 3948 "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 3954 "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 3968 "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 3974 "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 3991 "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 3996 "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 4017 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 4024 "querytransformparser.ypp"
+ {
+ /* This value is incremented before the action below is executed. */
+ ++parseInfo->elementConstructorDepth;
+ }
+ break;
+
+ case 389:
+/* Line 1269 of yacc.c. */
+#line 4029 "querytransformparser.ypp"
+ {
+ Q_ASSERT(5);
+ disallowedConstruct(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 4063 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = false;
+ }
+ break;
+
+ case 391:
+/* Line 1269 of yacc.c. */
+#line 4067 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = true;
+ }
+ break;
+
+ case 392:
+/* Line 1269 of yacc.c. */
+#line 4075 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 4087 "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 4092 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 4099 "querytransformparser.ypp"
+ {
+ disallowedConstruct(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 4110 "querytransformparser.ypp"
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 397:
+/* Line 1269 of yacc.c. */
+#line 4114 "querytransformparser.ypp"
+ {
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 398:
+/* Line 1269 of yacc.c. */
+#line 4117 "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 4123 "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 4129 "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 4144 "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 4148 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new NCNameConstructor((yyvsp[(1) - (1)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 405:
+/* Line 1269 of yacc.c. */
+#line 4157 "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 4162 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (1)].itemType), Cardinality::exactlyOne());
+ }
+ break;
+
+ case 407:
+/* Line 1269 of yacc.c. */
+#line 4166 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), Cardinality::zeroOrOne());
+ }
+ break;
+
+ case 408:
+/* Line 1269 of yacc.c. */
+#line 4171 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = CommonSequenceTypes::ZeroOrMoreItems;
+ }
+ break;
+
+ case 409:
+/* Line 1269 of yacc.c. */
+#line 4175 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = (yyvsp[(2) - (2)].sequenceType);
+ }
+ break;
+
+ case 410:
+/* Line 1269 of yacc.c. */
+#line 4180 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), (yyvsp[(2) - (2)].cardinality));
+ }
+ break;
+
+ case 411:
+/* Line 1269 of yacc.c. */
+#line 4185 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = CommonSequenceTypes::Empty;
+ }
+ break;
+
+ case 412:
+/* Line 1269 of yacc.c. */
+#line 4189 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::exactlyOne();}
+ break;
+
+ case 413:
+/* Line 1269 of yacc.c. */
+#line 4190 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::oneOrMore();}
+ break;
+
+ case 414:
+/* Line 1269 of yacc.c. */
+#line 4191 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::zeroOrMore();}
+ break;
+
+ case 415:
+/* Line 1269 of yacc.c. */
+#line 4192 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::zeroOrOne();}
+ break;
+
+ case 419:
+/* Line 1269 of yacc.c. */
+#line 4198 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::item;
+ }
+ break;
+
+ case 420:
+/* Line 1269 of yacc.c. */
+#line 4203 "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 4247 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::node;
+ }
+ break;
+
+ case 429:
+/* Line 1269 of yacc.c. */
+#line 4252 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::document;
+ }
+ break;
+
+ case 430:
+/* Line 1269 of yacc.c. */
+#line 4257 "querytransformparser.ypp"
+ {
+ // TODO support for document element testing
+ (yyval.itemType) = BuiltinTypes::document;
+ }
+ break;
+
+ case 433:
+/* Line 1269 of yacc.c. */
+#line 4266 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::text;
+ }
+ break;
+
+ case 434:
+/* Line 1269 of yacc.c. */
+#line 4271 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::comment;
+ }
+ break;
+
+ case 435:
+/* Line 1269 of yacc.c. */
+#line 4276 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::pi;
+ }
+ break;
+
+ case 436:
+/* Line 1269 of yacc.c. */
+#line 4281 "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 4286 "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 4305 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 441:
+/* Line 1269 of yacc.c. */
+#line 4310 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 442:
+/* Line 1269 of yacc.c. */
+#line 4315 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(BuiltinTypes::attribute, (yyvsp[(3) - (4)].qName));
+ }
+ break;
+
+ case 443:
+/* Line 1269 of yacc.c. */
+#line 4319 "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 4331 "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 4344 "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 4354 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::element;
+ }
+ break;
+
+ case 447:
+/* Line 1269 of yacc.c. */
+#line 4359 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::element;
+ }
+ break;
+
+ case 448:
+/* Line 1269 of yacc.c. */
+#line 4364 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(BuiltinTypes::element, (yyvsp[(3) - (4)].qName));
+ }
+ break;
+
+ case 449:
+/* Line 1269 of yacc.c. */
+#line 4369 "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 4383 "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 4400 "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 4412 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 457:
+/* Line 1269 of yacc.c. */
+#line 4424 "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 4438 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 463:
+/* Line 1269 of yacc.c. */
+#line 4442 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, (yyvsp[(2) - (2)].sval));
+ }
+ break;
+
+ case 466:
+/* Line 1269 of yacc.c. */
+#line 4450 "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 471:
+/* Line 1269 of yacc.c. */
+#line 4463 "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 4475 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->fromClarkName((yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+
+/* Line 1269 of yacc.c. */
+#line 7643 "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 4479 "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 0000000000..fcf8896d31
--- /dev/null
+++ b/src/xmlpatterns/parser/qquerytransformparser_p.h
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+/* 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
+
+/* 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 0000000000..eecd5b299f
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenizer_p.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..6e9c343612
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenlookup.cpp
@@ -0,0 +1,404 @@
+/* C++ code produced by gperf version 3.0.2 */
+/* 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 80 "TokenLookup.gperf"
+
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+#line 74 "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 125 "TokenLookup.gperf"
+ {"eq", EQ},
+ {"",ERROR},
+#line 103 "TokenLookup.gperf"
+ {"by", BY},
+#line 126 "TokenLookup.gperf"
+ {"every", EVERY},
+ {"",ERROR},
+#line 96 "TokenLookup.gperf"
+ {"as", AS},
+ {"",ERROR},
+#line 121 "TokenLookup.gperf"
+ {"else", ELSE},
+#line 190 "TokenLookup.gperf"
+ {"where", WHERE},
+#line 177 "TokenLookup.gperf"
+ {"stable", STABLE},
+#line 99 "TokenLookup.gperf"
+ {"at", AT},
+ {"",ERROR},
+#line 104 "TokenLookup.gperf"
+ {"case", CASE},
+ {"",ERROR},
+#line 102 "TokenLookup.gperf"
+ {"boundary-space", BOUNDARY_SPACE},
+#line 120 "TokenLookup.gperf"
+ {"element", ELEMENT},
+#line 105 "TokenLookup.gperf"
+ {"castable", CASTABLE},
+#line 100 "TokenLookup.gperf"
+ {"attribute", ATTRIBUTE},
+ {"",ERROR},
+#line 127 "TokenLookup.gperf"
+ {"except", EXCEPT},
+#line 134 "TokenLookup.gperf"
+ {"ge", GE},
+ {"",ERROR},
+#line 106 "TokenLookup.gperf"
+ {"cast", CAST},
+#line 183 "TokenLookup.gperf"
+ {"treat", TREAT},
+#line 191 "TokenLookup.gperf"
+ {"xquery", XQUERY},
+#line 154 "TokenLookup.gperf"
+ {"ne", NE},
+ {"",ERROR},
+#line 171 "TokenLookup.gperf"
+ {"satisfies", SATISFIES},
+ {"",ERROR}, {"",ERROR},
+#line 136 "TokenLookup.gperf"
+ {"gt", GT},
+#line 124 "TokenLookup.gperf"
+ {"encoding", ENCODING},
+#line 97 "TokenLookup.gperf"
+ {"ascending", ASCENDING},
+ {"",ERROR},
+#line 98 "TokenLookup.gperf"
+ {"assign", ASSIGN},
+#line 112 "TokenLookup.gperf"
+ {"declare", DECLARE},
+#line 135 "TokenLookup.gperf"
+ {"greatest", GREATEST},
+#line 181 "TokenLookup.gperf"
+ {"then", THEN},
+ {"",ERROR},
+#line 94 "TokenLookup.gperf"
+ {"ancestor-or-self", ANCESTOR_OR_SELF},
+#line 148 "TokenLookup.gperf"
+ {"le", LE},
+#line 119 "TokenLookup.gperf"
+ {"document-node", DOCUMENT_NODE},
+#line 180 "TokenLookup.gperf"
+ {"text", TEXT},
+ {"",ERROR},
+#line 174 "TokenLookup.gperf"
+ {"schema", SCHEMA},
+ {"",ERROR},
+#line 118 "TokenLookup.gperf"
+ {"document", DOCUMENT},
+ {"",ERROR},
+#line 114 "TokenLookup.gperf"
+ {"descendant", DESCENDANT},
+ {"",ERROR},
+#line 150 "TokenLookup.gperf"
+ {"lt", LT},
+#line 95 "TokenLookup.gperf"
+ {"and", AND},
+#line 155 "TokenLookup.gperf"
+ {"node", NODE},
+#line 147 "TokenLookup.gperf"
+ {"least", LEAST},
+#line 172 "TokenLookup.gperf"
+ {"schema-attribute", SCHEMA_ATTRIBUTE},
+ {"",ERROR},
+#line 128 "TokenLookup.gperf"
+ {"external", EXTERNAL},
+ {"",ERROR},
+#line 116 "TokenLookup.gperf"
+ {"descending", DESCENDING},
+#line 157 "TokenLookup.gperf"
+ {"no-preserve", NO_PRESERVE},
+#line 113 "TokenLookup.gperf"
+ {"default", DEFAULT},
+#line 149 "TokenLookup.gperf"
+ {"let", LET},
+#line 173 "TokenLookup.gperf"
+ {"schema-element", SCHEMA_ELEMENT},
+ {"",ERROR}, {"",ERROR},
+#line 110 "TokenLookup.gperf"
+ {"construction", CONSTRUCTION},
+#line 115 "TokenLookup.gperf"
+ {"descendant-or-self", DESCENDANT_OR_SELF},
+#line 175 "TokenLookup.gperf"
+ {"self", SELF},
+#line 156 "TokenLookup.gperf"
+ {"no-inherit", NO_INHERIT},
+ {"",ERROR},
+#line 131 "TokenLookup.gperf"
+ {"follows", FOLLOWS},
+#line 93 "TokenLookup.gperf"
+ {"ancestor", ANCESTOR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 182 "TokenLookup.gperf"
+ {"to", TO},
+#line 133 "TokenLookup.gperf"
+ {"function", FUNCTION},
+#line 108 "TokenLookup.gperf"
+ {"collation", COLLATION},
+ {"",ERROR},
+#line 178 "TokenLookup.gperf"
+ {"strict", STRICT},
+ {"",ERROR},
+#line 146 "TokenLookup.gperf"
+ {"lax", LAX},
+ {"",ERROR},
+#line 122 "TokenLookup.gperf"
+ {"empty", EMPTY},
+ {"",ERROR},
+#line 158 "TokenLookup.gperf"
+ {"of", OF},
+#line 168 "TokenLookup.gperf"
+ {"preserve", PRESERVE},
+#line 129 "TokenLookup.gperf"
+ {"following", FOLLOWING},
+ {"",ERROR}, {"",ERROR},
+#line 144 "TokenLookup.gperf"
+ {"is", IS},
+#line 165 "TokenLookup.gperf"
+ {"precedes", PRECEDES},
+#line 123 "TokenLookup.gperf"
+ {"empty-sequence", EMPTY_SEQUENCE},
+ {"",ERROR}, {"",ERROR},
+#line 130 "TokenLookup.gperf"
+ {"following-sibling", FOLLOWING_SIBLING},
+#line 142 "TokenLookup.gperf"
+ {"instance", INSTANCE},
+#line 186 "TokenLookup.gperf"
+ {"unordered", UNORDERED},
+#line 101 "TokenLookup.gperf"
+ {"base-uri", BASEURI},
+#line 170 "TokenLookup.gperf"
+ {"return", RETURN},
+ {"",ERROR},
+#line 187 "TokenLookup.gperf"
+ {"validate", VALIDATE},
+ {"",ERROR},
+#line 111 "TokenLookup.gperf"
+ {"copy-namespaces", COPY_NAMESPACES},
+#line 159 "TokenLookup.gperf"
+ {"option", OPTION},
+#line 138 "TokenLookup.gperf"
+ {"if", IF},
+ {"",ERROR},
+#line 166 "TokenLookup.gperf"
+ {"preceding", PRECEDING},
+ {"",ERROR}, {"",ERROR},
+#line 141 "TokenLookup.gperf"
+ {"in", IN},
+ {"",ERROR},
+#line 143 "TokenLookup.gperf"
+ {"intersect", INTERSECT},
+#line 185 "TokenLookup.gperf"
+ {"union", UNION},
+ {"",ERROR},
+#line 167 "TokenLookup.gperf"
+ {"preceding-sibling", PRECEDING_SIBLING},
+#line 161 "TokenLookup.gperf"
+ {"ordering", ORDERING},
+#line 176 "TokenLookup.gperf"
+ {"some", SOME},
+#line 107 "TokenLookup.gperf"
+ {"child", CHILD},
+ {"",ERROR},
+#line 160 "TokenLookup.gperf"
+ {"ordered", ORDERED},
+#line 188 "TokenLookup.gperf"
+ {"variable", VARIABLE},
+ {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 163 "TokenLookup.gperf"
+ {"or", OR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 109 "TokenLookup.gperf"
+ {"comment", COMMENT},
+ {"",ERROR}, {"",ERROR},
+#line 184 "TokenLookup.gperf"
+ {"typeswitch", TYPESWITCH},
+ {"",ERROR},
+#line 140 "TokenLookup.gperf"
+ {"inherit", INHERIT},
+#line 117 "TokenLookup.gperf"
+ {"div", DIV},
+ {"",ERROR}, {"",ERROR},
+#line 152 "TokenLookup.gperf"
+ {"module", MODULE},
+ {"",ERROR},
+#line 132 "TokenLookup.gperf"
+ {"for", FOR},
+#line 153 "TokenLookup.gperf"
+ {"namespace", NAMESPACE},
+ {"",ERROR}, {"",ERROR},
+#line 189 "TokenLookup.gperf"
+ {"version", VERSION},
+ {"",ERROR}, {"",ERROR},
+#line 179 "TokenLookup.gperf"
+ {"strip", STRIP},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 162 "TokenLookup.gperf"
+ {"order", ORDER},
+#line 164 "TokenLookup.gperf"
+ {"parent", PARENT},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 151 "TokenLookup.gperf"
+ {"mod", MOD},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR},
+#line 139 "TokenLookup.gperf"
+ {"import", IMPORT},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 169 "TokenLookup.gperf"
+ {"processing-instruction", PROCESSING_INSTRUCTION},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 145 "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 137 "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 192 "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 0000000000..15852d9f8e
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenrevealer.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..a1530b0821
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenrevealer_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..5393f12cee
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokensource.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..41b7be6442
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokensource_p.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..93974a48a7
--- /dev/null
+++ b/src/xmlpatterns/parser/querytransformparser.ypp
@@ -0,0 +1,4572 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+%{
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#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);
+}
+
+/**
+ * @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, 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 which is
+ * unavailable in XPath.
+ *
+ * If @p isInternal is @c true, no error is raised. Otherwise, if the current
+ * language is not XQuery, an error is raised.
+ */
+static void disallowedConstruct(const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const bool isInternal = false)
+{
+ if(!isInternal && parseInfo->languageAccent != QXmlQuery::XQuery10)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered which only is allowed in XQuery."),
+ 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 by 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
+ {
+ disallowedConstruct(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
+ {
+ disallowedConstruct(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
+ {
+ disallowedConstruct(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 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
+ {
+ disallowedConstruct(parseInfo, @$);
+ }
+| BaseURIDecl
+| ConstructionDecl
+ {
+ disallowedConstruct(parseInfo, @$);
+ }
+| OrderingModeDecl
+ {
+ disallowedConstruct(parseInfo, @$);
+ }
+| EmptyOrderDecl
+ {
+ disallowedConstruct(parseInfo, @$);
+ }
+| CopyNamespacesDecl
+
+Import: SchemaImport /* [8] */
+| ModuleImport
+
+Separator: SEMI_COLON /* [9] */
+
+NamespaceDecl: DECLARE NAMESPACE NCNAME G_EQ URILiteral IsInternal Separator /* [10] */
+ {
+ if(!$6)
+ disallowedConstruct(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] */
+ {
+ disallowedConstruct(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] */
+ {
+ disallowedConstruct(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] */
+ {
+ disallowedConstruct(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)
+ disallowedConstruct(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] */
+ {
+ disallowedConstruct(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] */
+ {
+ $$ = 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] */
+ {
+ $$ = 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] */
+ {
+ disallowedConstruct(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] */
+ {
+ $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo);
+ }
+
+OrExpr: AndExpr /* [46] */
+| OrExpr OR AndExpr
+ {
+ $$ = create(new OrExpression($1, $3), @$, parseInfo);
+ }
+
+AndExpr: ComparisonExpr /* [47] */
+| AndExpr AND ComparisonExpr
+ {
+ $$ = create(new AndExpression($1, $3), @$, parseInfo);
+ }
+
+ComparisonExpr: RangeExpr /* [48] */
+| ValueComp
+| GeneralComp
+| NodeComp
+
+RangeExpr: AdditiveExpr /* [49] */
+| AdditiveExpr TO AdditiveExpr
+ {
+ $$ = create(new RangeExpression($1, $3), @$, parseInfo);
+ }
+
+AdditiveExpr: MultiplicativeExpr /* [50] */
+| AdditiveExpr AdditiveOperator MultiplicativeExpr
+ {
+ $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
+ }
+
+AdditiveOperator: PLUS {$$ = AtomicMathematician::Add;} /* [X] */
+| MINUS {$$ = AtomicMathematician::Substract;}
+
+MultiplicativeExpr: UnionExpr /* [51] */
+| MultiplicativeExpr MultiplyOperator UnionExpr
+ {
+ $$ = 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
+ {
+ $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
+ }
+
+IntersectExceptExpr: InstanceOfExpr /* [53] */
+| IntersectExceptExpr IntersectOperator InstanceOfExpr
+ {
+ $$ = 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
+ {
+ $$ = create(new InstanceOf($1,
+ SequenceType::Ptr($4)), @$, parseInfo);
+ }
+
+TreatExpr: CastableExpr /* [55] */
+| CastableExpr TREAT AS SequenceType
+ {
+ $$ = create(new TreatAs($1, $4), @$, parseInfo);
+ }
+
+CastableExpr: CastExpr /* [56] */
+| CastExpr CASTABLE AS SingleType
+ {
+ $$ = create(new CastableAs($1, $4), @$, parseInfo);
+ }
+
+CastExpr: UnaryExpr /* [57] */
+| UnaryExpr CAST AS SingleType
+ {
+ $$ = create(new CastAs($1, $4), @$, parseInfo);
+ }
+
+UnaryExpr: ValueExpr /* [58] */
+| UnaryOperator UnaryExpr
+ {
+ $$ = 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] */
+ {
+ $$ = 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] */
+ {
+ disallowedConstruct(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] */
+ {
+ /* 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] */
+ {
+ disallowedConstruct(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] */
+{
+ Q_ASSERT(!$2.isEmpty());
+ $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo);
+}
+
+| DECLARE NAMESPACE NCNAME G_EQ STRING_LITERAL CURLY_LBRACE /* [X] */
+ {
+ 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;
+ }
+
+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] */
+ {
+ $$ = 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
+
+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
+ {
+ const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName($1);
+ $$ = LocalNameTest::create(parseInfo->nodeTestSource, c);
+ }
+
+FilterExpr: PrimaryExpr /* [81] */
+| FilterExpr LBRACKET Expr RBRACKET
+ {
+ $$ = 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] */
+ {
+ $$ = createNumericLiteral<Double>($1, @$, parseInfo);
+ }
+| NUMBER
+ {
+ $$ = createNumericLiteral<Numeric>($1, @$, parseInfo);
+ }
+
+VarRef: DOLLAR VarName /* [87] */
+ {
+ $$ = 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] */
+ {
+ $$ = $2;
+ }
+| LPAREN RPAREN
+ {
+ $$ = create(new EmptySequence, @$, parseInfo);
+ }
+
+ContextItemExpr: DOT /* [90] */
+ {
+ $$ = create(new ContextItem(), @$, parseInfo);
+ }
+
+OrderingExpr: OrderingMode EnclosedExpr /* [X] */
+ {
+ $$ = $2;
+ }
+
+FunctionCallExpr: FunctionName LPAREN FunctionArguments RPAREN /* [93] */
+ {
+ 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] */
+ {
+ disallowedConstruct(parseInfo, @$);
+ }
+| ComputedConstructor
+
+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] */
+ {
+ disallowedConstruct(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);
+ disallowedConstruct(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] */
+ {
+ disallowedConstruct(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] */
+ {
+ disallowedConstruct(parseInfo, @$, $2);
+
+ $$ = create(new CommentConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
+ }
+
+CompPIConstructor: PROCESSING_INSTRUCTION CompPIName EnclosedOptionalExpr /* [116] */
+ {
+ disallowedConstruct(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] */
+| XPATH2_STRING_LITERAL
+
+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 0000000000..7e96f13f59
--- /dev/null
+++ b/src/xmlpatterns/parser/qxquerytokenizer.cpp
@@ -0,0 +1,2249 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..4ef7a5f80a
--- /dev/null
+++ b/src/xmlpatterns/parser/qxquerytokenizer_p.h
@@ -0,0 +1,332 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..11d12f87fd
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenizer.cpp
@@ -0,0 +1,2717 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "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 0000000000..9fb43c7b60
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenizer_p.h
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..9184de7b5f
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup.cpp
@@ -0,0 +1,3006 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* 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 0000000000..228eae2c2f
--- /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) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+</prolog>
+
+ </boilerplate>
+
+</tokenAutomaton>
diff --git a/src/xmlpatterns/parser/qxslttokenlookup_p.h b/src/xmlpatterns/parser/qxslttokenlookup_p.h
new file mode 100644
index 0000000000..c9551e3e22
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+/* 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 0000000000..8ec655d039
--- /dev/null
+++ b/src/xmlpatterns/parser/trolltechHeader.txt
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
diff --git a/src/xmlpatterns/parser/winCEWorkaround.sed b/src/xmlpatterns/parser/winCEWorkaround.sed
new file mode 100644
index 0000000000..d1c09e83e5
--- /dev/null
+++ b/src/xmlpatterns/parser/winCEWorkaround.sed
@@ -0,0 +1,20 @@
+/\/\* 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\
+
diff --git a/src/xmlpatterns/projection/projection.pri b/src/xmlpatterns/projection/projection.pri
new file mode 100644
index 0000000000..530041d499
--- /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 0000000000..fd0ef290d3
--- /dev/null
+++ b/src/xmlpatterns/projection/qdocumentprojector.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..39e74e48be
--- /dev/null
+++ b/src/xmlpatterns/projection/qdocumentprojector_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..8f549024d6
--- /dev/null
+++ b/src/xmlpatterns/projection/qprojectedexpression_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..8c5e552d54
--- /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 0000000000..d62a42a7ff
--- /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) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+</prolog>
+
+ </boilerplate>
+
+</tokenAutomaton>
diff --git a/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl b/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl
new file mode 100644
index 0000000000..16084a0a4b
--- /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 0000000000..322c50ebd3
--- /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 0000000000..e09a61854d
--- /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)
diff --git a/src/xmlpatterns/type/qabstractnodetest.cpp b/src/xmlpatterns/type/qabstractnodetest.cpp
new file mode 100644
index 0000000000..12860ca109
--- /dev/null
+++ b/src/xmlpatterns/type/qabstractnodetest.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..c1abbb513b
--- /dev/null
+++ b/src/xmlpatterns/type/qabstractnodetest_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..80b7010d6a
--- /dev/null
+++ b/src/xmlpatterns/type/qanyitemtype.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+
+#include "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 0000000000..04f82b2270
--- /dev/null
+++ b/src/xmlpatterns/type/qanyitemtype_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..baf4226720
--- /dev/null
+++ b/src/xmlpatterns/type/qanynodetype.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..f34b4a11cf
--- /dev/null
+++ b/src/xmlpatterns/type/qanynodetype_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..c685d54d2b
--- /dev/null
+++ b/src/xmlpatterns/type/qanysimpletype.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qanysimpletype_p.h b/src/xmlpatterns/type/qanysimpletype_p.h
new file mode 100644
index 0000000000..b91c7d09d6
--- /dev/null
+++ b/src/xmlpatterns/type/qanysimpletype_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.com>
+ */
+ class AnySimpleType : public AnyType
+ {
+ public:
+ 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;
+
+ 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 0000000000..95ad2b3099
--- /dev/null
+++ b/src/xmlpatterns/type/qanytype.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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;
+}
+
+SchemaType::DerivationMethod AnyType::derivationMethod() const
+{
+ return NoDerivation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qanytype_p.h b/src/xmlpatterns/type/qanytype_p.h
new file mode 100644
index 0000000000..70477af7b9
--- /dev/null
+++ b/src/xmlpatterns/type/qanytype_p.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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;
+
+ 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 0000000000..5376d6f7d4
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocator.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..14e6360eef
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocator_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AtomicCasterLocator_H
+#define Patternist_AtomicCasterLocator_H
+
+#include "qatomictypedispatch_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @author Frans Englich <fenglich@trolltech.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 0000000000..9e1e444922
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocators.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..aa905de123
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccasterlocators_p.h
@@ -0,0 +1,909 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..5aa55b1d19
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocator.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..d18e6d98b3
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocator_p.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d400a5ef1a
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocators.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..b9aa36fded
--- /dev/null
+++ b/src/xmlpatterns/type/qatomiccomparatorlocators_p.h
@@ -0,0 +1,356 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.com>
+ */
+ class BooleanComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const BooleanType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class Base64BinaryComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const Base64BinaryType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class HexBinaryComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const HexBinaryType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class QNameComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const QNameType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.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 <fenglich@trolltech.com>
+ */
+ class GYearComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class GMonthComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class GYearMonthComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GYearMonthType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class GMonthDayComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GMonthDayType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class GDayComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const GDayType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DateTimeComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateTimeType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class SchemaTimeComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const SchemaTimeType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.com>
+ */
+ class DateComparatorLocator : public AtomicComparatorLocator
+ {
+ using AtomicComparatorLocator::visit;
+ virtual AtomicTypeVisitorResult::Ptr visit(const DateType *,
+ const qint16 op,
+ const SourceLocationReflection *const) const;
+ };
+
+ /**
+ * @author Frans Englich <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..c7650c9118
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocator.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..19ee6e71bc
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocator_p.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..92d7b2c75f
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocators.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..5ef958a21d
--- /dev/null
+++ b/src/xmlpatterns/type/qatomicmathematicianlocators_p.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..45f291a0d3
--- /dev/null
+++ b/src/xmlpatterns/type/qatomictype.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..92b7853523
--- /dev/null
+++ b/src/xmlpatterns/type/qatomictype_p.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..2158fd8381
--- /dev/null
+++ b/src/xmlpatterns/type/qatomictypedispatch_p.h
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..662308cc28
--- /dev/null
+++ b/src/xmlpatterns/type/qbasictypesfactory.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+
+#include "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 0000000000..9b2db3edf6
--- /dev/null
+++ b/src/xmlpatterns/type/qbasictypesfactory_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..48106a7b24
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictype.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..de94fa1bf3
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictype_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..ac38f5efe9
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictypes.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..3906978279
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinatomictypes_p.h
@@ -0,0 +1,789 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..d3d55adebe
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinnodetype.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by 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 0000000000..edb4c74d46
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltinnodetype_p.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..7c350ae542
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltintypes.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..4271d7d173
--- /dev/null
+++ b/src/xmlpatterns/type/qbuiltintypes_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..9d62d864e8
--- /dev/null
+++ b/src/xmlpatterns/type/qcardinality.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..9beecc3dd6
--- /dev/null
+++ b/src/xmlpatterns/type/qcardinality_p.h
@@ -0,0 +1,544 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..42ca749259
--- /dev/null
+++ b/src/xmlpatterns/type/qcommonsequencetypes.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..a4e61ab0c9
--- /dev/null
+++ b/src/xmlpatterns/type/qcommonsequencetypes_p.h
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0e240dcc68
--- /dev/null
+++ b/src/xmlpatterns/type/qebvtype.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "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 0000000000..555842e4ca
--- /dev/null
+++ b/src/xmlpatterns/type/qebvtype_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..3696ef6988
--- /dev/null
+++ b/src/xmlpatterns/type/qemptysequencetype.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..badd23164b
--- /dev/null
+++ b/src/xmlpatterns/type/qemptysequencetype_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..4db2583c9c
--- /dev/null
+++ b/src/xmlpatterns/type/qgenericsequencetype.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..e4302cfedd
--- /dev/null
+++ b/src/xmlpatterns/type/qgenericsequencetype_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..862f37f685
--- /dev/null
+++ b/src/xmlpatterns/type/qitemtype.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..c396149303
--- /dev/null
+++ b/src/xmlpatterns/type/qitemtype_p.h
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..92f677ae11
--- /dev/null
+++ b/src/xmlpatterns/type/qlocalnametest.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "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 0000000000..d15ccae7f2
--- /dev/null
+++ b/src/xmlpatterns/type/qlocalnametest_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..e7481ca576
--- /dev/null
+++ b/src/xmlpatterns/type/qmultiitemtype.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..06a1348617
--- /dev/null
+++ b/src/xmlpatterns/type/qmultiitemtype_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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/qnamespacenametest.cpp b/src/xmlpatterns/type/qnamespacenametest.cpp
new file mode 100644
index 0000000000..95f19a51a8
--- /dev/null
+++ b/src/xmlpatterns/type/qnamespacenametest.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..2b1ee461b2
--- /dev/null
+++ b/src/xmlpatterns/type/qnamespacenametest_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..b7d42d81df
--- /dev/null
+++ b/src/xmlpatterns/type/qnonetype.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "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 0000000000..aa739d2dd6
--- /dev/null
+++ b/src/xmlpatterns/type/qnonetype_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..6df26c2d6d
--- /dev/null
+++ b/src/xmlpatterns/type/qnumerictype.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..a6e249b29f
--- /dev/null
+++ b/src/xmlpatterns/type/qnumerictype_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..354b69037c
--- /dev/null
+++ b/src/xmlpatterns/type/qprimitives_p.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Primitives_H
+#define Patternist_Primitives_H
+
+#include <QtGlobal>
+
+/**
+ * @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 <fenglich@trolltech.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 <fenglich@trolltech.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 0000000000..929ed5a057
--- /dev/null
+++ b/src/xmlpatterns/type/qqnametest.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QHash>
+
+#include "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 0000000000..9166c875d1
--- /dev/null
+++ b/src/xmlpatterns/type/qqnametest_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..e828cac1f4
--- /dev/null
+++ b/src/xmlpatterns/type/qschemacomponent.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..749210af56
--- /dev/null
+++ b/src/xmlpatterns/type/qschemacomponent_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..b4d6bc0f00
--- /dev/null
+++ b/src/xmlpatterns/type/qschematype.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/type/qschematype_p.h b/src/xmlpatterns/type/qschematype_p.h
new file mode 100644
index 0000000000..30f63c8a06
--- /dev/null
+++ b/src/xmlpatterns/type/qschematype_p.h
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SchemaType_H
+#define Patternist_SchemaType_H
+
+#include "qnamepool_p.h"
+#include "qschemacomponent_p.h"
+#include "qxmlname.h"
+
+template<typename N, typename M> class QHash;
+
+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 <fenglich@trolltech.com>
+ */
+ class SchemaType : public SchemaComponent
+ {
+ public:
+
+ typedef QExplicitlySharedDataPointer<SchemaType> Ptr;
+ typedef QHash<QXmlName, SchemaType::Ptr> Hash;
+
+ /**
+ * 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
+ };
+
+ 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 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
+ * therfore 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.
+ */
+ 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.
+ */
+ bool isComplexType() const;
+ };
+}
+
+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 0000000000..fae1c4640d
--- /dev/null
+++ b/src/xmlpatterns/type/qschematypefactory.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..72ce9feb3f
--- /dev/null
+++ b/src/xmlpatterns/type/qschematypefactory_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..31efa62c03
--- /dev/null
+++ b/src/xmlpatterns/type/qsequencetype.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..016bffd094
--- /dev/null
+++ b/src/xmlpatterns/type/qsequencetype_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c419af6360
--- /dev/null
+++ b/src/xmlpatterns/type/qtypechecker.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 neccessarily 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 0000000000..d9ca1a134c
--- /dev/null
+++ b/src/xmlpatterns/type/qtypechecker_p.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..33042c1fe6
--- /dev/null
+++ b/src/xmlpatterns/type/quntyped.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..1b7f48b530
--- /dev/null
+++ b/src/xmlpatterns/type/quntyped_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..1ec67bf6c9
--- /dev/null
+++ b/src/xmlpatterns/type/qxsltnodetest.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "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 0000000000..1f75a88b9f
--- /dev/null
+++ b/src/xmlpatterns/type/qxsltnodetest_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..ef5976a9b5
--- /dev/null
+++ b/src/xmlpatterns/type/type.pri
@@ -0,0 +1,70 @@
+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/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/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 0000000000..1e3d773edf
--- /dev/null
+++ b/src/xmlpatterns/utils/qautoptr.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QPatternist::AutoPtr
+ \brief A smart pointer very similar to std::auto_ptr.
+ \internal
+ \since 4.4
+ \ingroup misc
+
+ */
+
diff --git a/src/xmlpatterns/utils/qautoptr_p.h b/src/xmlpatterns/utils/qautoptr_p.h
new file mode 100644
index 0000000000..9f40400df3
--- /dev/null
+++ b/src/xmlpatterns/utils/qautoptr_p.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef 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;
+ }
+
+#ifndef QT_NO_MEMBER_TEMPLATES
+ 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())
+ {
+ }
+#endif
+
+ 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 0000000000..6c9cf57978
--- /dev/null
+++ b/src/xmlpatterns/utils/qcommonnamespaces_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..7979bf0bf3
--- /dev/null
+++ b/src/xmlpatterns/utils/qcppcastinghelper_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..d270250f9b
--- /dev/null
+++ b/src/xmlpatterns/utils/qdebug_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 0000000000..fd67cf317b
--- /dev/null
+++ b/src/xmlpatterns/utils/qdelegatingnamespaceresolver.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..ef7d4de8da
--- /dev/null
+++ b/src/xmlpatterns/utils/qdelegatingnamespaceresolver_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..dd1ab9ffeb
--- /dev/null
+++ b/src/xmlpatterns/utils/qgenericnamespaceresolver.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..2bb6aff85d
--- /dev/null
+++ b/src/xmlpatterns/utils/qgenericnamespaceresolver_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely 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 <fenglich@trolltech.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 0000000000..a6f1b21dc2
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamepool.cpp
@@ -0,0 +1,418 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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 0000000000..f348d1be79
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamepool_p.h
@@ -0,0 +1,556 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..7fa3a6dd01
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamespacebinding_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..0c837d014b
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamespaceresolver.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..d76f709e68
--- /dev/null
+++ b/src/xmlpatterns/utils/qnamespaceresolver_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..c694ad42db
--- /dev/null
+++ b/src/xmlpatterns/utils/qnodenamespaceresolver.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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 0000000000..123cfbe5a9
--- /dev/null
+++ b/src/xmlpatterns/utils/qnodenamespaceresolver_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..51e8063cda
--- /dev/null
+++ b/src/xmlpatterns/utils/qoutputvalidator.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..15734ffc6c
--- /dev/null
+++ b/src/xmlpatterns/utils/qoutputvalidator_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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 0000000000..990867d7ae
--- /dev/null
+++ b/src/xmlpatterns/utils/qpatternistlocale.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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 0000000000..e3f645f9a9
--- /dev/null
+++ b/src/xmlpatterns/utils/qpatternistlocale_p.h
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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.
+ *
+ * This file was originally called qpatternistlocale_p.h. However, it broke build on MS
+ * Windows, because it override the locale.h system header.
+ */
+
+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)
+ };
+
+ static 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 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 0000000000..127e21f3fc
--- /dev/null
+++ b/src/xmlpatterns/utils/qxpathhelper.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "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. */
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/utils/qxpathhelper_p.h b/src/xmlpatterns/utils/qxpathhelper_p.h
new file mode 100644
index 0000000000..7bf33e6d12
--- /dev/null
+++ b/src/xmlpatterns/utils/qxpathhelper_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_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 <fenglich@trolltech.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);
+
+ /**
+ * @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 0000000000..2db91c2525
--- /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 0000000000..e9d8af9d09
--- /dev/null
+++ b/src/xmlpatterns/xmlpatterns.pro
@@ -0,0 +1,35 @@
+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: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/type/type.pri)
+include($$PWD/utils/utils.pri)
+include($$PWD/qobjectmodel/qobjectmodel.pri)
+
+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/
+ }
+}