LibreOffice Module forms (master) 1
xpathlib.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <string.h>
22
24#include <o3tl/string_view.hxx>
25#include <sal/types.h>
26#include <rtl/ustring.hxx>
27#include <rtl/string.hxx>
28#include <rtl/strbuf.hxx>
29#include <tools/date.hxx>
30#include <tools/time.hxx>
31#include <tools/datetime.hxx>
32
33#include <com/sun/star/uno/Reference.hxx>
34#include <com/sun/star/uno/Sequence.hxx>
35#include <com/sun/star/xforms/XModel.hpp>
36#include <com/sun/star/xml/dom/XNode.hpp>
37#include <com/sun/star/xml/dom/XDocument.hpp>
38#include <com/sun/star/lang/XUnoTunnel.hpp>
39
40#include <boost/lexical_cast.hpp>
41#include <libxml/xpathInternals.h>
42
43#include "xpathlib.hxx"
44#include "extension.hxx"
45
46// C interface
47
48using namespace com::sun::star::uno;
49using namespace com::sun::star::xml::dom;
50using namespace com::sun::star::xforms;
51using namespace com::sun::star::lang;
52
53xmlXPathFunction xforms_lookupFunc(void *, const xmlChar *xname, const xmlChar *)
54{
55
56 const char *name = reinterpret_cast<char const *>(xname);
57 if (strcmp("boolean-from-string", name)==0)
59 else if ((strcmp("if", name))==0)
60 return xforms_ifFunction;
61 else if ((strcmp("avg", name))==0)
62 return xforms_avgFunction;
63 else if ((strcmp("min", name))==0)
64 return xforms_minFunction;
65 else if ((strcmp("max", name))==0)
66 return xforms_maxFunction;
67 else if ((strcmp("count-non-empty", name))==0)
69 else if ((strcmp("index", name))==0)
71 else if ((strcmp("property", name))==0)
73 else if ((strcmp("now", name))==0)
74 return xforms_nowFunction;
75 else if ((strcmp("days-from-date", name))==0)
77 else if ((strcmp("seconds-from-dateTime", name))==0)
79 else if ((strcmp("seconds", name))==0)
81 else if ((strcmp("months", name))==0)
83 else if ((strcmp("instance", name))==0)
85 else if ((strcmp("current", name))==0)
87 else
88 return nullptr;
89}
90
91// boolean functions
92void xforms_booleanFromStringFunction(xmlXPathParserContextPtr ctxt, int nargs)
93{
94 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
95 xmlChar *pString = xmlXPathPopString(ctxt);
96 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
97 OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
98 if (aString.equalsIgnoreAsciiCase("true") ||
99 aString.equalsIgnoreAsciiCase("1"))
100 xmlXPathReturnTrue(ctxt);
101 else if (aString.equalsIgnoreAsciiCase("false") ||
102 aString.equalsIgnoreAsciiCase("0"))
103 xmlXPathReturnFalse(ctxt);
104 else
105 XP_ERROR(XPATH_NUMBER_ERROR);
106}
107
108void xforms_ifFunction(xmlXPathParserContextPtr ctxt, int nargs)
109{
110 if (nargs != 3) XP_ERROR(XPATH_INVALID_ARITY);
111 xmlChar *s2 = xmlXPathPopString(ctxt);
112
113 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
114 xmlChar *s1 = xmlXPathPopString(ctxt);
115 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
116 bool aBool = xmlXPathPopBoolean(ctxt);
117 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
118
119 if (aBool)
120 xmlXPathReturnString(ctxt, s1);
121 else
122 xmlXPathReturnString(ctxt, s2);
123
124}
125
126// Number Functions
127void xforms_avgFunction(xmlXPathParserContextPtr ctxt, int nargs)
128{
129 // use sum(), div() and count()
130 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
131
132 // save nodeset
133 xmlXPathObjectPtr pObject = valuePop(ctxt);
134 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
135 //push back a copy
136 valuePush(ctxt, xmlXPathObjectCopy(pObject));
137 // get the Sum
138 xmlXPathSumFunction(ctxt, 1);
139 double nSum = xmlXPathPopNumber(ctxt);
140 // push a copy once more
141 valuePush(ctxt, xmlXPathObjectCopy(pObject));
142 xmlXPathCountFunction(ctxt, 1);
143 double nCount = xmlXPathPopNumber(ctxt);
144 // push args for div()
145 xmlXPathReturnNumber(ctxt, nSum);
146 xmlXPathReturnNumber(ctxt, nCount);
147 xmlXPathDivValues(ctxt);
148 // the result is now on the ctxt stack
149 xmlXPathFreeObject(pObject);
150}
151
152void xforms_minFunction(xmlXPathParserContextPtr ctxt, int nargs)
153{
154 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
155 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
156 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
157 double nMinimum = 0;
158 for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
159 {
160 double nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
161 if (xmlXPathIsNaN(nNumber))
162 {
163 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
164 return;
165 }
166 if (i == 0)
167 nMinimum = nNumber;
168 else if (nNumber < nMinimum)
169 nMinimum = nNumber;
170 }
171 xmlXPathReturnNumber(ctxt, nMinimum);
172}
173
174void xforms_maxFunction(xmlXPathParserContextPtr ctxt, int nargs)
175{
176 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
177 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
178 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
179 double nMaximum = 0;
180 for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
181 {
182 double nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
183 if (xmlXPathIsNaN(nNumber))
184 {
185 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
186 return;
187 }
188 if (i == 0)
189 nMaximum = nNumber;
190 else if (nNumber > nMaximum)
191 nMaximum = nNumber;
192 }
193 xmlXPathReturnNumber(ctxt, nMaximum);
194}
195void xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt, int nargs)
196{
197 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
198 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
199 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
200 sal_Int32 nNotEmpty = 0;
201 for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
202 {
203 const xmlChar *aString = xmlXPathCastNodeToString(xmlXPathNodeSetItem(pNodeSet, i));
204 if (*aString != 0) nNotEmpty++;
205 }
206 xmlXPathReturnNumber(ctxt, nNotEmpty);
207}
208void xforms_indexFunction(xmlXPathParserContextPtr /*ctxt*/, int /*nargs*/)
209{
210 // function index takes a string argument that is the IDREF of a
211 // 'repeat' and returns the current 1-based position of the repeat
212 // index of the identified repeat -- see xforms/9.3.1
213
214 // doc.getElementByID
215 // (...)
216}
217
218// String Functions
219void xforms_propertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
220{
221 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
222 xmlChar* pString = xmlXPathPopString(ctxt);
223 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
224 OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
225 if (aString.equalsIgnoreAsciiCase("version"))
226 xmlXPathReturnString(ctxt, reinterpret_cast<xmlChar *>(const_cast<char *>("1.0")));
227 else if (aString.equalsIgnoreAsciiCase("conformance-level"))
228 xmlXPathReturnString(ctxt, reinterpret_cast<xmlChar *>(const_cast<char *>("conformance")));
229 else
230 xmlXPathReturnEmptyString(ctxt);
231}
232
233// Date and Time Functions
234
235static OString makeDateTimeString (const DateTime& aDateTime)
236{
237 OStringBuffer aDateTimeString;
238 aDateTimeString.append(static_cast<sal_Int32>(aDateTime.GetYear()));
239 aDateTimeString.append('-');
240 if (aDateTime.GetMonth()<10) aDateTimeString.append('0');
241 aDateTimeString.append(static_cast<sal_Int32>(aDateTime.GetMonth()));
242 aDateTimeString.append('-');
243 if (aDateTime.GetDay()<10) aDateTimeString.append('0');
244 aDateTimeString.append(static_cast<sal_Int32>(aDateTime.GetDay()));
245 aDateTimeString.append('T');
246 if (aDateTime.GetHour()<10) aDateTimeString.append('0');
247 aDateTimeString.append(static_cast<sal_Int32>(aDateTime.GetHour()));
248 aDateTimeString.append(':');
249 if (aDateTime.GetMin()<10) aDateTimeString.append('0');
250 aDateTimeString.append(static_cast<sal_Int32>(aDateTime.GetMin()));
251 aDateTimeString.append(':');
252 if (aDateTime.GetSec()<10) aDateTimeString.append('0');
253 aDateTimeString.append(static_cast<sal_Int32>(aDateTime.GetSec()));
254 aDateTimeString.append('Z');
255
256 return aDateTimeString.makeStringAndClear();
257}
258
259// returns current system date and time in canonical xsd:dateTime
260// format
261void xforms_nowFunction(xmlXPathParserContextPtr ctxt, int /*nargs*/)
262{
263 /*
264 A single lexical representation, which is a subset of the lexical representations
265 allowed by [ISO 8601], is allowed for dateTime. This lexical representation is the
266 [ISO 8601] extended format CCYY-MM-DDThh:mm:ss where "CC" represents the century,
267 "YY" the year, "MM" the month and "DD" the day, preceded by an optional leading "-"
268 sign to indicate a negative number. If the sign is omitted, "+" is assumed. The letter
269 "T" is the date/time separator and "hh", "mm", "ss" represent hour, minute and second
270 respectively.
271 */
272
273 /*
274 3.2.7.2 Canonical representation
275 The canonical representation for dateTime is defined by prohibiting certain options
276 from the Lexical representation (par.3.2.7.1). Specifically, either the time zone must
277 be omitted or, if present, the time zone must be Coordinated Universal tools::Time (UTC)
278 indicated by a "Z".
279 */
280 OString aDateTimeString;
281 if (std::getenv("STABLE_FIELDS_HACK"))
282 aDateTimeString = makeDateTimeString(DateTime(DateTime::EMPTY));
283 else
284 aDateTimeString = makeDateTimeString(DateTime(DateTime::SYSTEM));
285 xmlChar *pString = static_cast<xmlChar*>(xmlMalloc(aDateTimeString.getLength()+1));
286 strncpy(reinterpret_cast<char*>(pString), aDateTimeString.getStr(), aDateTimeString.getLength());
287 pString[aDateTimeString.getLength()] = 0;
288 xmlXPathReturnString(ctxt, pString);
289}
290
291static bool parseDateTime(std::u16string_view aString, DateTime& aDateTime)
292{
293 // take apart a canonical literal xsd:dateTime string
294 //CCYY-MM-DDThh:mm:ss(Z)
295
296 OUString aDateTimeString( o3tl::trim(aString) );
297
298 // check length
299 if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
300 return false;
301
302 sal_Int32 nIndex = 0;
303 sal_Int32 nYear = o3tl::toInt32(o3tl::getToken(aDateTimeString, 0, '-', nIndex));
304 sal_Int32 nMonth = o3tl::toInt32(o3tl::getToken(aDateTimeString, 0, '-', nIndex));
305 sal_Int32 nDay = o3tl::toInt32(o3tl::getToken(aDateTimeString, 0, 'T', nIndex));
306 sal_Int32 nHour = o3tl::toInt32(o3tl::getToken(aDateTimeString, 0, ':', nIndex));
307 sal_Int32 nMinute = o3tl::toInt32(o3tl::getToken(aDateTimeString, 0, ':', nIndex));
308 sal_Int32 nSecond = o3tl::toInt32(o3tl::getToken(aDateTimeString, 0, 'Z', nIndex));
309
310 Date tmpDate(static_cast<sal_uInt16>(nDay), static_cast<sal_uInt16>(nMonth), static_cast<sal_uInt16>(nYear));
311 tools::Time tmpTime(nHour, nMinute, nSecond);
312 DateTime tmpDateTime(tmpDate, tmpTime);
313 if (aString.rfind('Z') == std::u16string_view::npos)
314 tmpDateTime.ConvertToUTC();
315
316 aDateTime = tmpDateTime;
317
318 return true;
319}
320
321
322void xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt, int nargs)
323{
324 // number of days from 1970-01-01 to supplied xsd:date(Time)
325
326 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
327 xmlChar* pString = xmlXPathPopString(ctxt);
328 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
329 OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
330
331 DateTime aDateTime( DateTime::EMPTY );
332 if (parseDateTime(aString, aDateTime))
333 {
334 Date aReferenceDate(1, 1, 1970);
335 sal_Int32 nDays = aDateTime - aReferenceDate;
336 xmlXPathReturnNumber(ctxt, nDays);
337 }
338 else
339 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
340
341
342}
343
344
345void xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt, int nargs)
346{
347 // number of seconds from 1970-01-01T00:00:00Z to supplied xsd:date(Time)
348
349 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
350 xmlChar* pString = xmlXPathPopString(ctxt);
351 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
352 OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
353
354 DateTime aDateTime( DateTime::EMPTY );
355
356 if (parseDateTime(aString, aDateTime))
357 {
358 Date aReferenceDate(1, 1, 1970);
359 sal_Int32 nDays = aDateTime - aReferenceDate;
360 sal_Int32 nSeconds = nDays * 24 * 60 * 60;
361 nSeconds += aDateTime.GetHour() * 60 * 60;
362 nSeconds += aDateTime.GetMin() * 60;
363 nSeconds += aDateTime.GetSec();
364 xmlXPathReturnNumber(ctxt, nSeconds);
365 }
366 else
367 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
368
369}
370
371static bool parseDuration(const xmlChar* aString, bool& bNegative, sal_Int32& nYears, sal_Int32& nMonth, sal_Int32& nDays,
372 sal_Int32& nHours, sal_Int32& nMinutes, sal_Int32& nSeconds)
373{
374 bool bTime = false; // in part after T
375 const xmlChar *pString = aString;
376
377 if (pString[0] == '-') {
378 bNegative = true;
379 pString++;
380 }
381
382 if (pString[0] != 'P')
383 {
384 return false;
385 }
386
387 pString++;
388 const xmlChar* pToken = pString;
389 while(pToken[0] != 0)
390 {
391 switch(pToken[0]) {
392 case 'Y':
393 nYears = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
394 pString = ++pToken;
395 break;
396 case 'M':
397 if (!bTime)
398 nMonth = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
399 else
400 nMinutes = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
401 pString = ++pToken;
402 break;
403 case 'D':
404 nDays = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
405 pString = ++pToken;
406 break;
407 case 'H':
408 nHours = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
409 pString = ++pToken;
410 break;
411 case 'S':
412 nSeconds = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
413 pString = ++pToken;
414 break;
415 case 'T':
416 bTime = true;
417 pString = ++pToken;
418 break;
419 default:
420 pToken++;
421 }
422 }
423 return true;
424}
425
426void xforms_secondsFunction(xmlXPathParserContextPtr ctxt, int nargs)
427{
428 // convert a xsd:duration to seconds
429 // (-)PnYnMnDTnHnMnS
430 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
431 xmlChar* pString = xmlXPathPopString(ctxt);
432 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
433
434 bool bNegative = false;
435 sal_Int32 nYears = 0;
436 sal_Int32 nMonths = 0;
437 sal_Int32 nDays = 0;
438 sal_Int32 nHours = 0;
439 sal_Int32 nMinutes = 0;
440 sal_Int32 nSeconds = 0;
441
442 if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
443 {
444 nSeconds += nMinutes*60;
445 nSeconds += nHours*60*60;
446 nSeconds += nDays*24*60*60;
447 // year and month are ignored according to spec
448 if (bNegative)
449 nSeconds = 0 - nSeconds;
450 xmlXPathReturnNumber(ctxt, nSeconds);
451 }
452 else
453 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
454}
455
456void xforms_monthsFunction(xmlXPathParserContextPtr ctxt, int nargs)
457{
458 // convert a xsd:duration to seconds
459 // (-)PnYnMnDTnHnMnS
460 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
461 xmlChar* pString = xmlXPathPopString(ctxt);
462 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
463
464 bool bNegative = false;
465 sal_Int32 nYears = 0;
466 sal_Int32 nMonths = 0;
467 sal_Int32 nDays = 0;
468 sal_Int32 nHours = 0;
469 sal_Int32 nMinutes = 0;
470 sal_Int32 nSeconds = 0;
471
472 if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
473 {
474 nMonths += nYears*12;
475 // Days, Hours, Minutes and seconds are ignored, see spec
476 if (bNegative)
477 nMonths = 0 - nMonths;
478 xmlXPathReturnNumber(ctxt, nMonths);
479 }
480 else
481 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
482
483}
484
485// Node-set Functions
486void xforms_instanceFunction(xmlXPathParserContextPtr ctxt, int nargs)
487{
488 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
489 xmlChar *pString = xmlXPathPopString(ctxt);
490 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
491 OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
492
493 Reference< XModel > aModel = static_cast<CLibxml2XFormsExtension*>(ctxt->context->funcLookupData)->getModel();
494 if (aModel.is())
495 {
496 Reference< XDocument > aInstance = aModel->getInstanceDocument(aString);
497 if (aInstance.is())
498 {
499 try {
500 // xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val);
501 Reference< XUnoTunnel > aTunnel(aInstance, UNO_QUERY_THROW);
502 xmlNodePtr pNode = comphelper::getSomething_cast<xmlNode>(aTunnel->getSomething(Sequence<sal_Int8>()));
503 xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
504 xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
505 } catch (const RuntimeException&)
506 {
507 xmlXPathReturnEmptyNodeSet(ctxt);
508 }
509 }
510 else
511 xmlXPathReturnEmptyNodeSet(ctxt);
512 }
513 else
514 xmlXPathReturnEmptyNodeSet(ctxt);
515
516}
517
518// Node-set Functions, XForms 1.1
519void xforms_currentFunction(xmlXPathParserContextPtr ctxt, int nargs)
520{
521 if (nargs != 0) XP_ERROR(XPATH_INVALID_ARITY);
522
523 Reference< XNode > aNode = static_cast<CLibxml2XFormsExtension*>(ctxt->context->funcLookupData)->getContextNode();
524
525 if (aNode.is())
526 {
527 try {
528 Reference< XUnoTunnel > aTunnel(aNode, UNO_QUERY_THROW);
529 xmlNodePtr pNode = comphelper::getSomething_cast<xmlNode>(aTunnel->getSomething(Sequence<sal_Int8>()));
530 xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
531 xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
532 }
533 catch (const RuntimeException&)
534 {
535 xmlXPathReturnEmptyNodeSet(ctxt);
536 }
537 }
538 else
539 xmlXPathReturnEmptyNodeSet(ctxt);
540}
541
542/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void ConvertToUTC()
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
sal_uInt16 GetSec() const
sal_uInt16 GetMin() const
sal_uInt16 GetHour() const
int nCount
EmbeddedObjectRef * pObject
const char * name
sal_Int32 nIndex
int i
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
static OString makeDateTimeString(const DateTime &aDateTime)
Definition: xpathlib.cxx:235
void xforms_booleanFromStringFunction(xmlXPathParserContextPtr ctxt, int nargs)
xmlXPathParserContext:
Definition: xpathlib.cxx:92
void xforms_instanceFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:486
void xforms_avgFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:127
void xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:322
void xforms_nowFunction(xmlXPathParserContextPtr ctxt, int)
Definition: xpathlib.cxx:261
void xforms_currentFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:519
void xforms_secondsFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:426
void xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:345
static bool parseDuration(const xmlChar *aString, bool &bNegative, sal_Int32 &nYears, sal_Int32 &nMonth, sal_Int32 &nDays, sal_Int32 &nHours, sal_Int32 &nMinutes, sal_Int32 &nSeconds)
Definition: xpathlib.cxx:371
void xforms_maxFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:174
void xforms_ifFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:108
void xforms_minFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:152
xmlXPathFunction xforms_lookupFunc(void *, const xmlChar *xname, const xmlChar *)
Definition: xpathlib.cxx:53
void xforms_monthsFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:456
void xforms_indexFunction(xmlXPathParserContextPtr, int)
Definition: xpathlib.cxx:208
void xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:195
void xforms_propertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: xpathlib.cxx:219
static bool parseDateTime(std::u16string_view aString, DateTime &aDateTime)
Definition: xpathlib.cxx:291