1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtXmlPatterns module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qbuiltintypes_p.h" |
41 | #include "qcommonnamespaces_p.h" |
42 | #include "qcommonsequencetypes_p.h" |
43 | #include "qcommonvalues_p.h" |
44 | #include "qpatternistlocale_p.h" |
45 | #include "qxmlname.h" |
46 | |
47 | /* Functions */ |
48 | #include "qaccessorfns_p.h" |
49 | #include "qaggregatefns_p.h" |
50 | #include "qbooleanfns_p.h" |
51 | #include "qcomparestringfns_p.h" |
52 | #include "qcontextfns_p.h" |
53 | #include "qnodefns_p.h" |
54 | #include "qnumericfns_p.h" |
55 | #include "qsequencefns_p.h" |
56 | #include "qsequencegeneratingfns_p.h" |
57 | #include "qstringvaluefns_p.h" |
58 | #include "qsubstringfns_p.h" |
59 | |
60 | #include "qxpath10corefunctions_p.h" |
61 | |
62 | QT_BEGIN_NAMESPACE |
63 | |
64 | using namespace QPatternist; |
65 | |
66 | Expression::Ptr XPath10CoreFunctions::retrieveExpression(const QXmlName name, |
67 | const Expression::List &args, |
68 | const FunctionSignature::Ptr &sign) const |
69 | { |
70 | Q_ASSERT(sign); |
71 | |
72 | Expression::Ptr fn; |
73 | #define testFN(ln, cname) else if(name.localName() == StandardLocalNames::ln) fn = Expression::Ptr(new cname()) |
74 | |
75 | if(false) /* Dummy for the macro handling. Will be optimized away anyway. */ |
76 | return Expression::Ptr(); |
77 | /* Alphabetic order. */ |
78 | testFN(boolean, BooleanFN); |
79 | testFN(ceiling, CeilingFN); |
80 | testFN(concat, ConcatFN); |
81 | testFN(contains, ContainsFN); |
82 | testFN(count, CountFN); |
83 | testFN(False, FalseFN); |
84 | testFN(floor, FloorFN); |
85 | testFN(id, IdFN); |
86 | testFN(lang, LangFN); |
87 | testFN(last, LastFN); |
88 | testFN(local_name, LocalNameFN); |
89 | testFN(name, NameFN); |
90 | testFN(namespace_uri, NamespaceURIFN); |
91 | testFN(normalize_space, NormalizeSpaceFN); |
92 | testFN(Not, NotFN); |
93 | testFN(number, NumberFN); |
94 | testFN(position, PositionFN); |
95 | testFN(round, RoundFN); |
96 | testFN(starts_with, StartsWithFN); |
97 | testFN(string, StringFN); |
98 | testFN(string_length, StringLengthFN); |
99 | testFN(substring, SubstringFN); |
100 | testFN(substring_after, SubstringAfterFN); |
101 | testFN(substring_before, SubstringBeforeFN); |
102 | testFN(sum, SumFN); |
103 | testFN(translate, TranslateFN); |
104 | testFN(True, TrueFN); |
105 | #undef testFN |
106 | |
107 | Q_ASSERT(fn); |
108 | fn->setOperands(args); |
109 | fn->as<FunctionCall>()->setSignature(sign); |
110 | |
111 | return fn; |
112 | } |
113 | |
114 | FunctionSignature::Ptr XPath10CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) |
115 | { |
116 | if(StandardNamespaces::fn != name.namespaceURI()) |
117 | return FunctionSignature::Ptr(); |
118 | |
119 | FunctionSignature::Ptr s(functionSignatures().value(akey: name)); |
120 | |
121 | if(!s) |
122 | { |
123 | const QXmlName::LocalNameCode localName(name.localName()); |
124 | |
125 | /* Alphabetic order. */ |
126 | if(StandardLocalNames::boolean == localName) |
127 | { |
128 | s = addFunction(localName: StandardLocalNames::boolean, minArgs: 1, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneBoolean); |
129 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::EBV); |
130 | } |
131 | else if(StandardLocalNames::ceiling == localName) |
132 | { |
133 | s = addFunction(localName: StandardLocalNames::ceiling, minArgs: 1, maxArgs: 1, returnType: CommonSequenceTypes::ZeroOrOneNumeric, |
134 | props: Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); |
135 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneNumeric); |
136 | } |
137 | else if(StandardLocalNames::concat == localName) |
138 | { |
139 | s = addFunction(localName: StandardLocalNames::concat, minArgs: 2, maxArgs: FunctionSignature::UnlimitedArity, |
140 | returnType: CommonSequenceTypes::ExactlyOneString); |
141 | s->appendArgument(name: argument(np, name: "arg1" ), type: CommonSequenceTypes::ZeroOrOneAtomicType); |
142 | s->appendArgument(name: argument(np, name: "arg2" ), type: CommonSequenceTypes::ZeroOrOneAtomicType); |
143 | } |
144 | else if(StandardLocalNames::contains == localName) |
145 | { |
146 | s = addFunction(localName: StandardLocalNames::contains, minArgs: 2, maxArgs: 3, returnType: CommonSequenceTypes::ExactlyOneBoolean, |
147 | props: Expression::LastOperandIsCollation); |
148 | s->appendArgument(name: argument(np, name: "arg1" ), type: CommonSequenceTypes::ZeroOrOneString); |
149 | s->appendArgument(name: argument(np, name: "arg2" ), type: CommonSequenceTypes::ZeroOrOneString); |
150 | s->appendArgument(name: argument(np, name: "collation" ), type: CommonSequenceTypes::ExactlyOneString); |
151 | } |
152 | else if(StandardLocalNames::count == localName) |
153 | { |
154 | s = addFunction(localName: StandardLocalNames::count, minArgs: 1, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneInteger, id: Expression::IDCountFN); |
155 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrMoreItems); |
156 | } |
157 | else if(StandardLocalNames::False == localName) |
158 | { |
159 | s = addFunction(localName: StandardLocalNames::False, minArgs: 0, maxArgs: 0, returnType: CommonSequenceTypes::ExactlyOneBoolean); |
160 | } |
161 | else if(StandardLocalNames::floor == localName) |
162 | { |
163 | s = addFunction(localName: StandardLocalNames::floor, minArgs: 1, maxArgs: 1, returnType: CommonSequenceTypes::ZeroOrOneNumeric, |
164 | props: Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); |
165 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneNumeric); |
166 | } |
167 | else if(StandardLocalNames::id == localName) |
168 | { |
169 | s = addFunction(localName: StandardLocalNames::id, minArgs: 1, maxArgs: 2, returnType: CommonSequenceTypes::ZeroOrMoreElements, |
170 | props: Expression::UseContextItem); |
171 | s->appendArgument(name: argument(np, name: "idrefs" ), type: CommonSequenceTypes::ZeroOrMoreStrings); |
172 | s->appendArgument(name: argument(np, name: "node" ), type: CommonSequenceTypes::ExactlyOneNode); |
173 | } |
174 | else if(StandardLocalNames::lang == localName) |
175 | { |
176 | s = addFunction(localName: StandardLocalNames::lang, minArgs: 1, maxArgs: 2, returnType: CommonSequenceTypes::ExactlyOneBoolean, |
177 | props: Expression::UseContextItem); |
178 | s->appendArgument(name: argument(np, name: "testLang" ), type: CommonSequenceTypes::ZeroOrOneString); |
179 | s->appendArgument(name: argument(np, name: "node" ), type: CommonSequenceTypes::ExactlyOneNode); |
180 | } |
181 | else if(StandardLocalNames::last == localName) |
182 | { |
183 | s = addFunction(localName: StandardLocalNames::last, minArgs: 0, maxArgs: 0, returnType: CommonSequenceTypes::ExactlyOneInteger, |
184 | props: Expression::DisableElimination | Expression::RequiresFocus); |
185 | } |
186 | else if(StandardLocalNames::local_name == localName) |
187 | { |
188 | s = addFunction(localName: StandardLocalNames::local_name, minArgs: 0, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneString, |
189 | props: Expression::UseContextItem); |
190 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneNode); |
191 | } |
192 | else if(StandardLocalNames::name == localName) |
193 | { |
194 | s = addFunction(localName: StandardLocalNames::name, minArgs: 0, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneString, |
195 | props: Expression::UseContextItem); |
196 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneNode); |
197 | } |
198 | else if(StandardLocalNames::namespace_uri == localName) |
199 | { |
200 | s = addFunction(localName: StandardLocalNames::namespace_uri, minArgs: 0, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneAnyURI, |
201 | props: Expression::UseContextItem); |
202 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneNode); |
203 | } |
204 | else if(StandardLocalNames::normalize_space == localName) |
205 | { |
206 | s = addFunction(localName: StandardLocalNames::normalize_space, minArgs: 0, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneString, |
207 | props: Expression::UseContextItem); |
208 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneString); |
209 | } |
210 | else if(StandardLocalNames::Not == localName) |
211 | { |
212 | s = addFunction(localName: StandardLocalNames::Not, minArgs: 1, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneBoolean); |
213 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::EBV); |
214 | } |
215 | else if(StandardLocalNames::number == localName) |
216 | { |
217 | s = addFunction(localName: StandardLocalNames::number, minArgs: 0, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneDouble, |
218 | props: Expression::UseContextItem); |
219 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneAtomicType); |
220 | } |
221 | else if(StandardLocalNames::position == localName) |
222 | { |
223 | s = addFunction(localName: StandardLocalNames::position, minArgs: 0, maxArgs: 0, returnType: CommonSequenceTypes::ExactlyOneInteger, |
224 | props: Expression::DisableElimination | Expression::RequiresFocus); |
225 | } |
226 | else if(StandardLocalNames::round == localName) |
227 | { |
228 | s = addFunction(localName: StandardLocalNames::round, minArgs: 1, maxArgs: 1, returnType: CommonSequenceTypes::ZeroOrOneNumeric, |
229 | props: Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); |
230 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneNumeric); |
231 | } |
232 | else if(StandardLocalNames::starts_with == localName) |
233 | { |
234 | s = addFunction(localName: StandardLocalNames::starts_with, minArgs: 2, maxArgs: 3, returnType: CommonSequenceTypes::ExactlyOneBoolean, |
235 | props: Expression::LastOperandIsCollation); |
236 | s->appendArgument(name: argument(np, name: "arg1" ), type: CommonSequenceTypes::ZeroOrOneString); |
237 | s->appendArgument(name: argument(np, name: "arg2" ), type: CommonSequenceTypes::ZeroOrOneString); |
238 | s->appendArgument(name: argument(np, name: "collation" ), type: CommonSequenceTypes::ExactlyOneString); |
239 | } |
240 | else if(StandardLocalNames::string == localName) |
241 | { |
242 | s = addFunction(localName: StandardLocalNames::string, minArgs: 0, maxArgs: 1, returnType: CommonSequenceTypes::ExactlyOneString, |
243 | props: Expression::UseContextItem); |
244 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneItem); |
245 | } |
246 | else if(StandardLocalNames::string_length == localName) |
247 | { |
248 | s = addFunction(localName: StandardLocalNames::string_length, minArgs: 0, maxArgs: 1, |
249 | returnType: CommonSequenceTypes::ExactlyOneInteger, |
250 | props: Expression::UseContextItem); |
251 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneString); |
252 | } |
253 | else if(StandardLocalNames::substring == localName) |
254 | { |
255 | s = addFunction(localName: StandardLocalNames::substring, minArgs: 2, maxArgs: 3, returnType: CommonSequenceTypes::ExactlyOneString); |
256 | s->appendArgument(name: argument(np, name: "sourceString" ), type: CommonSequenceTypes::ZeroOrOneString); |
257 | s->appendArgument(name: argument(np, name: "startingLoc" ), type: CommonSequenceTypes::ExactlyOneDouble); |
258 | s->appendArgument(name: argument(np, name: "length" ), type: CommonSequenceTypes::ExactlyOneDouble); |
259 | } |
260 | else if(StandardLocalNames::substring_after == localName) |
261 | { |
262 | s = addFunction(localName: StandardLocalNames::substring_after, minArgs: 2, maxArgs: 3, returnType: CommonSequenceTypes::ExactlyOneString, |
263 | props: Expression::LastOperandIsCollation); |
264 | s->appendArgument(name: argument(np, name: "arg1" ), type: CommonSequenceTypes::ZeroOrOneString); |
265 | s->appendArgument(name: argument(np, name: "arg2" ), type: CommonSequenceTypes::ZeroOrOneString); |
266 | s->appendArgument(name: argument(np, name: "collation" ), type: CommonSequenceTypes::ExactlyOneString); |
267 | } |
268 | else if(StandardLocalNames::substring_before == localName) |
269 | { |
270 | s = addFunction(localName: StandardLocalNames::substring_before, minArgs: 2, maxArgs: 3, returnType: CommonSequenceTypes::ExactlyOneString, |
271 | props: Expression::LastOperandIsCollation); |
272 | s->appendArgument(name: argument(np, name: "arg1" ), type: CommonSequenceTypes::ZeroOrOneString); |
273 | s->appendArgument(name: argument(np, name: "arg2" ), type: CommonSequenceTypes::ZeroOrOneString); |
274 | s->appendArgument(name: argument(np, name: "collation" ), type: CommonSequenceTypes::ExactlyOneString); |
275 | } |
276 | else if(StandardLocalNames::sum == localName) |
277 | { |
278 | s = addFunction(localName: StandardLocalNames::sum, minArgs: 1, maxArgs: 2, returnType: CommonSequenceTypes::ZeroOrOneAtomicType); |
279 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrMoreAtomicTypes); |
280 | s->appendArgument(name: argument(np, name: "zero" ), type: CommonSequenceTypes::ZeroOrOneAtomicType); |
281 | } |
282 | else if(StandardLocalNames::translate == localName) |
283 | { |
284 | s = addFunction(localName: StandardLocalNames::translate, minArgs: 3, maxArgs: 3, returnType: CommonSequenceTypes::ExactlyOneString); |
285 | s->appendArgument(name: argument(np, name: "arg" ), type: CommonSequenceTypes::ZeroOrOneString); |
286 | s->appendArgument(name: argument(np, name: "mapString" ), type: CommonSequenceTypes::ExactlyOneString); |
287 | s->appendArgument(name: argument(np, name: "transString" ), type: CommonSequenceTypes::ExactlyOneString); |
288 | } |
289 | else if(StandardLocalNames::True == localName) |
290 | { |
291 | s = addFunction(localName: StandardLocalNames::True, minArgs: 0, maxArgs: 0, returnType: CommonSequenceTypes::ExactlyOneBoolean); |
292 | } |
293 | } |
294 | |
295 | return s; |
296 | } |
297 | |
298 | QT_END_NAMESPACE |
299 | |