| Index: third_party/libxslt/libexslt/date.c
|
| diff --git a/third_party/libxslt/libexslt/date.c b/third_party/libxslt/libexslt/date.c
|
| deleted file mode 100644
|
| index 3af6f7fda2b9f35720202e51a1a7dbb972dbcfb5..0000000000000000000000000000000000000000
|
| --- a/third_party/libxslt/libexslt/date.c
|
| +++ /dev/null
|
| @@ -1,3911 +0,0 @@
|
| -/*
|
| - * date.c: Implementation of the EXSLT -- Dates and Times module
|
| - *
|
| - * References:
|
| - * http://www.exslt.org/date/date.html
|
| - *
|
| - * See Copyright for the status of this software.
|
| - *
|
| - * Authors:
|
| - * Charlie Bozeman <cbozeman@HiWAAY.net>
|
| - * Thomas Broyer <tbroyer@ltgt.net>
|
| - *
|
| - * TODO:
|
| - * elements:
|
| - * date-format
|
| - * functions:
|
| - * format-date
|
| - * parse-date
|
| - * sum
|
| - */
|
| -
|
| -#define IN_LIBEXSLT
|
| -#include "libexslt/libexslt.h"
|
| -
|
| -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
|
| -#include <win32config.h>
|
| -#else
|
| -#include "config.h"
|
| -#endif
|
| -
|
| -#if defined(HAVE_LOCALTIME_R) && defined(__GLIBC__) /* _POSIX_SOURCE required by gnu libc */
|
| -#ifndef _AIX51 /* but on AIX we're not using gnu libc */
|
| -#define _POSIX_SOURCE
|
| -#endif
|
| -#endif
|
| -
|
| -#include <libxml/tree.h>
|
| -#include <libxml/xpath.h>
|
| -#include <libxml/xpathInternals.h>
|
| -
|
| -#include <libxslt/xsltconfig.h>
|
| -#include <libxslt/xsltutils.h>
|
| -#include <libxslt/xsltInternals.h>
|
| -#include <libxslt/extensions.h>
|
| -
|
| -#include "exslt.h"
|
| -
|
| -#include <string.h>
|
| -
|
| -#ifdef HAVE_ERRNO_H
|
| -#include <errno.h>
|
| -#endif
|
| -#ifdef HAVE_MATH_H
|
| -#include <math.h>
|
| -#endif
|
| -
|
| -/* needed to get localtime_r on Solaris */
|
| -#ifdef __sun
|
| -#ifndef __EXTENSIONS__
|
| -#define __EXTENSIONS__
|
| -#endif
|
| -#endif
|
| -
|
| -#ifdef HAVE_TIME_H
|
| -#include <time.h>
|
| -#endif
|
| -
|
| -/*
|
| - * types of date and/or time (from schema datatypes)
|
| - * somewhat ordered from least specific to most specific (i.e.
|
| - * most truncated to least truncated).
|
| - */
|
| -typedef enum {
|
| - EXSLT_UNKNOWN = 0,
|
| - XS_TIME = 1, /* time is left-truncated */
|
| - XS_GDAY = (XS_TIME << 1),
|
| - XS_GMONTH = (XS_GDAY << 1),
|
| - XS_GMONTHDAY = (XS_GMONTH | XS_GDAY),
|
| - XS_GYEAR = (XS_GMONTH << 1),
|
| - XS_GYEARMONTH = (XS_GYEAR | XS_GMONTH),
|
| - XS_DATE = (XS_GYEAR | XS_GMONTH | XS_GDAY),
|
| - XS_DATETIME = (XS_DATE | XS_TIME),
|
| - XS_DURATION = (XS_GYEAR << 1)
|
| -} exsltDateType;
|
| -
|
| -/* Date value */
|
| -typedef struct _exsltDateValDate exsltDateValDate;
|
| -typedef exsltDateValDate *exsltDateValDatePtr;
|
| -struct _exsltDateValDate {
|
| - long year;
|
| - unsigned int mon :4; /* 1 <= mon <= 12 */
|
| - unsigned int day :5; /* 1 <= day <= 31 */
|
| - unsigned int hour :5; /* 0 <= hour <= 23 */
|
| - unsigned int min :6; /* 0 <= min <= 59 */
|
| - double sec;
|
| - unsigned int tz_flag :1; /* is tzo explicitely set? */
|
| - signed int tzo :12; /* -1440 <= tzo <= 1440 currently only -840 to +840 are needed */
|
| -};
|
| -
|
| -/* Duration value */
|
| -typedef struct _exsltDateValDuration exsltDateValDuration;
|
| -typedef exsltDateValDuration *exsltDateValDurationPtr;
|
| -struct _exsltDateValDuration {
|
| - long mon; /* mon stores years also */
|
| - long day;
|
| - double sec; /* sec stores min and hour also */
|
| -};
|
| -
|
| -typedef struct _exsltDateVal exsltDateVal;
|
| -typedef exsltDateVal *exsltDateValPtr;
|
| -struct _exsltDateVal {
|
| - exsltDateType type;
|
| - union {
|
| - exsltDateValDate date;
|
| - exsltDateValDuration dur;
|
| - } value;
|
| -};
|
| -
|
| -/****************************************************************
|
| - * *
|
| - * Compat./Port. macros *
|
| - * *
|
| - ****************************************************************/
|
| -
|
| -#if defined(HAVE_TIME_H) \
|
| - && (defined(HAVE_LOCALTIME) || defined(HAVE_LOCALTIME_R)) \
|
| - && (defined(HAVE_GMTIME) || defined(HAVE_GMTIME_R)) \
|
| - && defined(HAVE_TIME)
|
| -#define WITH_TIME
|
| -#endif
|
| -
|
| -/****************************************************************
|
| - * *
|
| - * Convenience macros and functions *
|
| - * *
|
| - ****************************************************************/
|
| -
|
| -#define IS_TZO_CHAR(c) \
|
| - ((c == 0) || (c == 'Z') || (c == '+') || (c == '-'))
|
| -
|
| -#define VALID_ALWAYS(num) (num >= 0)
|
| -#define VALID_YEAR(yr) (yr != 0)
|
| -#define VALID_MONTH(mon) ((mon >= 1) && (mon <= 12))
|
| -/* VALID_DAY should only be used when month is unknown */
|
| -#define VALID_DAY(day) ((day >= 1) && (day <= 31))
|
| -#define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23))
|
| -#define VALID_MIN(min) ((min >= 0) && (min <= 59))
|
| -#define VALID_SEC(sec) ((sec >= 0) && (sec < 60))
|
| -#define VALID_TZO(tzo) ((tzo > -1440) && (tzo < 1440))
|
| -#define IS_LEAP(y) \
|
| - (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
|
| -
|
| -static const unsigned long daysInMonth[12] =
|
| - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
| -static const unsigned long daysInMonthLeap[12] =
|
| - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
| -
|
| -#define MAX_DAYINMONTH(yr,mon) \
|
| - (IS_LEAP(yr) ? daysInMonthLeap[mon - 1] : daysInMonth[mon - 1])
|
| -
|
| -#define VALID_MDAY(dt) \
|
| - (IS_LEAP(dt->year) ? \
|
| - (dt->day <= daysInMonthLeap[dt->mon - 1]) : \
|
| - (dt->day <= daysInMonth[dt->mon - 1]))
|
| -
|
| -#define VALID_DATE(dt) \
|
| - (VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
|
| -
|
| -/*
|
| - hour and min structure vals are unsigned, so normal macros give
|
| - warnings on some compilers.
|
| -*/
|
| -#define VALID_TIME(dt) \
|
| - ((dt->hour <=23 ) && (dt->min <= 59) && \
|
| - VALID_SEC(dt->sec) && VALID_TZO(dt->tzo))
|
| -
|
| -#define VALID_DATETIME(dt) \
|
| - (VALID_DATE(dt) && VALID_TIME(dt))
|
| -
|
| -#define SECS_PER_MIN (60)
|
| -#define SECS_PER_HOUR (60 * SECS_PER_MIN)
|
| -#define SECS_PER_DAY (24 * SECS_PER_HOUR)
|
| -
|
| -static const unsigned long dayInYearByMonth[12] =
|
| - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
|
| -static const unsigned long dayInLeapYearByMonth[12] =
|
| - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
|
| -
|
| -#define DAY_IN_YEAR(day, month, year) \
|
| - ((IS_LEAP(year) ? \
|
| - dayInLeapYearByMonth[month - 1] : \
|
| - dayInYearByMonth[month - 1]) + day)
|
| -
|
| -/**
|
| - * _exsltDateParseGYear:
|
| - * @dt: pointer to a date structure
|
| - * @str: pointer to the string to analyze
|
| - *
|
| - * Parses a xs:gYear without time zone and fills in the appropriate
|
| - * field of the @dt structure. @str is updated to point just after the
|
| - * xs:gYear. It is supposed that @dt->year is big enough to contain
|
| - * the year.
|
| - *
|
| - * Returns 0 or the error code
|
| - */
|
| -static int
|
| -_exsltDateParseGYear (exsltDateValDatePtr dt, const xmlChar **str)
|
| -{
|
| - const xmlChar *cur = *str, *firstChar;
|
| - int isneg = 0, digcnt = 0;
|
| -
|
| - if (((*cur < '0') || (*cur > '9')) &&
|
| - (*cur != '-') && (*cur != '+'))
|
| - return -1;
|
| -
|
| - if (*cur == '-') {
|
| - isneg = 1;
|
| - cur++;
|
| - }
|
| -
|
| - firstChar = cur;
|
| -
|
| - while ((*cur >= '0') && (*cur <= '9')) {
|
| - dt->year = dt->year * 10 + (*cur - '0');
|
| - cur++;
|
| - digcnt++;
|
| - }
|
| -
|
| - /* year must be at least 4 digits (CCYY); over 4
|
| - * digits cannot have a leading zero. */
|
| - if ((digcnt < 4) || ((digcnt > 4) && (*firstChar == '0')))
|
| - return 1;
|
| -
|
| - if (isneg)
|
| - dt->year = - dt->year;
|
| -
|
| - if (!VALID_YEAR(dt->year))
|
| - return 2;
|
| -
|
| - *str = cur;
|
| -
|
| -#ifdef DEBUG_EXSLT_DATE
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "Parsed year %04i\n", dt->year);
|
| -#endif
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -/**
|
| - * FORMAT_GYEAR:
|
| - * @yr: the year to format
|
| - * @cur: a pointer to an allocated buffer
|
| - *
|
| - * Formats @yr in xsl:gYear format. Result is appended to @cur and
|
| - * @cur is updated to point after the xsl:gYear.
|
| - */
|
| -#define FORMAT_GYEAR(yr, cur) \
|
| - if (yr < 0) { \
|
| - *cur = '-'; \
|
| - cur++; \
|
| - } \
|
| - { \
|
| - long year = (yr < 0) ? - yr : yr; \
|
| - xmlChar tmp_buf[100], *tmp = tmp_buf; \
|
| - /* result is in reverse-order */ \
|
| - while (year > 0) { \
|
| - *tmp = '0' + (xmlChar)(year % 10); \
|
| - year /= 10; \
|
| - tmp++; \
|
| - } \
|
| - /* virtually adds leading zeros */ \
|
| - while ((tmp - tmp_buf) < 4) \
|
| - *tmp++ = '0'; \
|
| - /* restore the correct order */ \
|
| - while (tmp > tmp_buf) { \
|
| - tmp--; \
|
| - *cur = *tmp; \
|
| - cur++; \
|
| - } \
|
| - }
|
| -
|
| -/**
|
| - * PARSE_2_DIGITS:
|
| - * @num: the integer to fill in
|
| - * @cur: an #xmlChar *
|
| - * @func: validation function for the number
|
| - * @invalid: an integer
|
| - *
|
| - * Parses a 2-digits integer and updates @num with the value. @cur is
|
| - * updated to point just after the integer.
|
| - * In case of error, @invalid is set to %TRUE, values of @num and
|
| - * @cur are undefined.
|
| - */
|
| -#define PARSE_2_DIGITS(num, cur, func, invalid) \
|
| - if ((cur[0] < '0') || (cur[0] > '9') || \
|
| - (cur[1] < '0') || (cur[1] > '9')) \
|
| - invalid = 1; \
|
| - else { \
|
| - int val; \
|
| - val = (cur[0] - '0') * 10 + (cur[1] - '0'); \
|
| - if (!func(val)) \
|
| - invalid = 2; \
|
| - else \
|
| - num = val; \
|
| - } \
|
| - cur += 2;
|
| -
|
| -/**
|
| - * FORMAT_2_DIGITS:
|
| - * @num: the integer to format
|
| - * @cur: a pointer to an allocated buffer
|
| - *
|
| - * Formats a 2-digits integer. Result is appended to @cur and
|
| - * @cur is updated to point after the integer.
|
| - */
|
| -#define FORMAT_2_DIGITS(num, cur) \
|
| - *cur = '0' + ((num / 10) % 10); \
|
| - cur++; \
|
| - *cur = '0' + (num % 10); \
|
| - cur++;
|
| -
|
| -/**
|
| - * PARSE_FLOAT:
|
| - * @num: the double to fill in
|
| - * @cur: an #xmlChar *
|
| - * @invalid: an integer
|
| - *
|
| - * Parses a float and updates @num with the value. @cur is
|
| - * updated to point just after the float. The float must have a
|
| - * 2-digits integer part and may or may not have a decimal part.
|
| - * In case of error, @invalid is set to %TRUE, values of @num and
|
| - * @cur are undefined.
|
| - */
|
| -#define PARSE_FLOAT(num, cur, invalid) \
|
| - PARSE_2_DIGITS(num, cur, VALID_ALWAYS, invalid); \
|
| - if (!invalid && (*cur == '.')) { \
|
| - double mult = 1; \
|
| - cur++; \
|
| - if ((*cur < '0') || (*cur > '9')) \
|
| - invalid = 1; \
|
| - while ((*cur >= '0') && (*cur <= '9')) { \
|
| - mult /= 10; \
|
| - num += (*cur - '0') * mult; \
|
| - cur++; \
|
| - } \
|
| - }
|
| -
|
| -/**
|
| - * FORMAT_FLOAT:
|
| - * @num: the double to format
|
| - * @cur: a pointer to an allocated buffer
|
| - * @pad: a flag for padding to 2 integer digits
|
| - *
|
| - * Formats a float. Result is appended to @cur and @cur is updated to
|
| - * point after the integer. If the @pad flag is non-zero, then the
|
| - * float representation has a minimum 2-digits integer part. The
|
| - * fractional part is formatted if @num has a fractional value.
|
| - */
|
| -#define FORMAT_FLOAT(num, cur, pad) \
|
| - { \
|
| - xmlChar *sav, *str; \
|
| - if ((pad) && (num < 10.0)) \
|
| - *cur++ = '0'; \
|
| - str = xmlXPathCastNumberToString(num); \
|
| - sav = str; \
|
| - while (*str != 0) \
|
| - *cur++ = *str++; \
|
| - xmlFree(sav); \
|
| - }
|
| -
|
| -/**
|
| - * _exsltDateParseGMonth:
|
| - * @dt: pointer to a date structure
|
| - * @str: pointer to the string to analyze
|
| - *
|
| - * Parses a xs:gMonth without time zone and fills in the appropriate
|
| - * field of the @dt structure. @str is updated to point just after the
|
| - * xs:gMonth.
|
| - *
|
| - * Returns 0 or the error code
|
| - */
|
| -static int
|
| -_exsltDateParseGMonth (exsltDateValDatePtr dt, const xmlChar **str)
|
| -{
|
| - const xmlChar *cur = *str;
|
| - int ret = 0;
|
| -
|
| - PARSE_2_DIGITS(dt->mon, cur, VALID_MONTH, ret);
|
| - if (ret != 0)
|
| - return ret;
|
| -
|
| - *str = cur;
|
| -
|
| -#ifdef DEBUG_EXSLT_DATE
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "Parsed month %02i\n", dt->mon);
|
| -#endif
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -/**
|
| - * FORMAT_GMONTH:
|
| - * @mon: the month to format
|
| - * @cur: a pointer to an allocated buffer
|
| - *
|
| - * Formats @mon in xsl:gMonth format. Result is appended to @cur and
|
| - * @cur is updated to point after the xsl:gMonth.
|
| - */
|
| -#define FORMAT_GMONTH(mon, cur) \
|
| - FORMAT_2_DIGITS(mon, cur)
|
| -
|
| -/**
|
| - * _exsltDateParseGDay:
|
| - * @dt: pointer to a date structure
|
| - * @str: pointer to the string to analyze
|
| - *
|
| - * Parses a xs:gDay without time zone and fills in the appropriate
|
| - * field of the @dt structure. @str is updated to point just after the
|
| - * xs:gDay.
|
| - *
|
| - * Returns 0 or the error code
|
| - */
|
| -static int
|
| -_exsltDateParseGDay (exsltDateValDatePtr dt, const xmlChar **str)
|
| -{
|
| - const xmlChar *cur = *str;
|
| - int ret = 0;
|
| -
|
| - PARSE_2_DIGITS(dt->day, cur, VALID_DAY, ret);
|
| - if (ret != 0)
|
| - return ret;
|
| -
|
| - *str = cur;
|
| -
|
| -#ifdef DEBUG_EXSLT_DATE
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "Parsed day %02i\n", dt->day);
|
| -#endif
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -/**
|
| - * FORMAT_GDAY:
|
| - * @dt: the #exsltDateValDate to format
|
| - * @cur: a pointer to an allocated buffer
|
| - *
|
| - * Formats @dt in xsl:gDay format. Result is appended to @cur and
|
| - * @cur is updated to point after the xsl:gDay.
|
| - */
|
| -#define FORMAT_GDAY(dt, cur) \
|
| - FORMAT_2_DIGITS(dt->day, cur)
|
| -
|
| -/**
|
| - * FORMAT_DATE:
|
| - * @dt: the #exsltDateValDate to format
|
| - * @cur: a pointer to an allocated buffer
|
| - *
|
| - * Formats @dt in xsl:date format. Result is appended to @cur and
|
| - * @cur is updated to point after the xsl:date.
|
| - */
|
| -#define FORMAT_DATE(dt, cur) \
|
| - FORMAT_GYEAR(dt->year, cur); \
|
| - *cur = '-'; \
|
| - cur++; \
|
| - FORMAT_GMONTH(dt->mon, cur); \
|
| - *cur = '-'; \
|
| - cur++; \
|
| - FORMAT_GDAY(dt, cur);
|
| -
|
| -/**
|
| - * _exsltDateParseTime:
|
| - * @dt: pointer to a date structure
|
| - * @str: pointer to the string to analyze
|
| - *
|
| - * Parses a xs:time without time zone and fills in the appropriate
|
| - * fields of the @dt structure. @str is updated to point just after the
|
| - * xs:time.
|
| - * In case of error, values of @dt fields are undefined.
|
| - *
|
| - * Returns 0 or the error code
|
| - */
|
| -static int
|
| -_exsltDateParseTime (exsltDateValDatePtr dt, const xmlChar **str)
|
| -{
|
| - const xmlChar *cur = *str;
|
| - unsigned int hour = 0; /* use temp var in case str is not xs:time */
|
| - int ret = 0;
|
| -
|
| - PARSE_2_DIGITS(hour, cur, VALID_HOUR, ret);
|
| - if (ret != 0)
|
| - return ret;
|
| -
|
| - if (*cur != ':')
|
| - return 1;
|
| - cur++;
|
| -
|
| - /* the ':' insures this string is xs:time */
|
| - dt->hour = hour;
|
| -
|
| - PARSE_2_DIGITS(dt->min, cur, VALID_MIN, ret);
|
| - if (ret != 0)
|
| - return ret;
|
| -
|
| - if (*cur != ':')
|
| - return 1;
|
| - cur++;
|
| -
|
| - PARSE_FLOAT(dt->sec, cur, ret);
|
| - if (ret != 0)
|
| - return ret;
|
| -
|
| - if (!VALID_TIME(dt))
|
| - return 2;
|
| -
|
| - *str = cur;
|
| -
|
| -#ifdef DEBUG_EXSLT_DATE
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "Parsed time %02i:%02i:%02.f\n",
|
| - dt->hour, dt->min, dt->sec);
|
| -#endif
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -/**
|
| - * FORMAT_TIME:
|
| - * @dt: the #exsltDateValDate to format
|
| - * @cur: a pointer to an allocated buffer
|
| - *
|
| - * Formats @dt in xsl:time format. Result is appended to @cur and
|
| - * @cur is updated to point after the xsl:time.
|
| - */
|
| -#define FORMAT_TIME(dt, cur) \
|
| - FORMAT_2_DIGITS(dt->hour, cur); \
|
| - *cur = ':'; \
|
| - cur++; \
|
| - FORMAT_2_DIGITS(dt->min, cur); \
|
| - *cur = ':'; \
|
| - cur++; \
|
| - FORMAT_FLOAT(dt->sec, cur, 1);
|
| -
|
| -/**
|
| - * _exsltDateParseTimeZone:
|
| - * @dt: pointer to a date structure
|
| - * @str: pointer to the string to analyze
|
| - *
|
| - * Parses a time zone without time zone and fills in the appropriate
|
| - * field of the @dt structure. @str is updated to point just after the
|
| - * time zone.
|
| - *
|
| - * Returns 0 or the error code
|
| - */
|
| -static int
|
| -_exsltDateParseTimeZone (exsltDateValDatePtr dt, const xmlChar **str)
|
| -{
|
| - const xmlChar *cur;
|
| - int ret = 0;
|
| -
|
| - if (str == NULL)
|
| - return -1;
|
| - cur = *str;
|
| - switch (*cur) {
|
| - case 0:
|
| - dt->tz_flag = 0;
|
| - dt->tzo = 0;
|
| - break;
|
| -
|
| - case 'Z':
|
| - dt->tz_flag = 1;
|
| - dt->tzo = 0;
|
| - cur++;
|
| - break;
|
| -
|
| - case '+':
|
| - case '-': {
|
| - int isneg = 0, tmp = 0;
|
| - isneg = (*cur == '-');
|
| -
|
| - cur++;
|
| -
|
| - PARSE_2_DIGITS(tmp, cur, VALID_HOUR, ret);
|
| - if (ret != 0)
|
| - return ret;
|
| -
|
| - if (*cur != ':')
|
| - return 1;
|
| - cur++;
|
| -
|
| - dt->tzo = tmp * 60;
|
| -
|
| - PARSE_2_DIGITS(tmp, cur, VALID_MIN, ret);
|
| - if (ret != 0)
|
| - return ret;
|
| -
|
| - dt->tzo += tmp;
|
| - if (isneg)
|
| - dt->tzo = - dt->tzo;
|
| -
|
| - if (!VALID_TZO(dt->tzo))
|
| - return 2;
|
| -
|
| - break;
|
| - }
|
| - default:
|
| - return 1;
|
| - }
|
| -
|
| - *str = cur;
|
| -
|
| -#ifdef DEBUG_EXSLT_DATE
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "Parsed time zone offset (%s) %i\n",
|
| - dt->tz_flag ? "explicit" : "implicit", dt->tzo);
|
| -#endif
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -/**
|
| - * FORMAT_TZ:
|
| - * @tzo: the timezone offset to format
|
| - * @cur: a pointer to an allocated buffer
|
| - *
|
| - * Formats @tzo timezone. Result is appended to @cur and
|
| - * @cur is updated to point after the timezone.
|
| - */
|
| -#define FORMAT_TZ(tzo, cur) \
|
| - if (tzo == 0) { \
|
| - *cur = 'Z'; \
|
| - cur++; \
|
| - } else { \
|
| - int aTzo = (tzo < 0) ? - tzo : tzo; \
|
| - int tzHh = aTzo / 60, tzMm = aTzo % 60; \
|
| - *cur = (tzo < 0) ? '-' : '+' ; \
|
| - cur++; \
|
| - FORMAT_2_DIGITS(tzHh, cur); \
|
| - *cur = ':'; \
|
| - cur++; \
|
| - FORMAT_2_DIGITS(tzMm, cur); \
|
| - }
|
| -
|
| -/****************************************************************
|
| - * *
|
| - * XML Schema Dates/Times Datatypes Handling *
|
| - * *
|
| - ****************************************************************/
|
| -
|
| -/**
|
| - * exsltDateCreateDate:
|
| - * @type: type to create
|
| - *
|
| - * Creates a new #exsltDateVal, uninitialized.
|
| - *
|
| - * Returns the #exsltDateValPtr
|
| - */
|
| -static exsltDateValPtr
|
| -exsltDateCreateDate (exsltDateType type)
|
| -{
|
| - exsltDateValPtr ret;
|
| -
|
| - ret = (exsltDateValPtr) xmlMalloc(sizeof(exsltDateVal));
|
| - if (ret == NULL) {
|
| - xsltGenericError(xsltGenericErrorContext,
|
| - "exsltDateCreateDate: out of memory\n");
|
| - return (NULL);
|
| - }
|
| - memset (ret, 0, sizeof(exsltDateVal));
|
| -
|
| - if (type != XS_DURATION) {
|
| - ret->value.date.mon = 1;
|
| - ret->value.date.day = 1;
|
| - }
|
| -
|
| - if (type != EXSLT_UNKNOWN)
|
| - ret->type = type;
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateFreeDate:
|
| - * @date: an #exsltDateValPtr
|
| - *
|
| - * Frees up the @date
|
| - */
|
| -static void
|
| -exsltDateFreeDate (exsltDateValPtr date) {
|
| - if (date == NULL)
|
| - return;
|
| -
|
| - xmlFree(date);
|
| -}
|
| -
|
| -/**
|
| - * PARSE_DIGITS:
|
| - * @num: the integer to fill in
|
| - * @cur: an #xmlChar *
|
| - * @num_type: an integer flag
|
| - *
|
| - * Parses a digits integer and updates @num with the value. @cur is
|
| - * updated to point just after the integer.
|
| - * In case of error, @num_type is set to -1, values of @num and
|
| - * @cur are undefined.
|
| - */
|
| -#define PARSE_DIGITS(num, cur, num_type) \
|
| - if ((*cur < '0') || (*cur > '9')) \
|
| - num_type = -1; \
|
| - else \
|
| - while ((*cur >= '0') && (*cur <= '9')) { \
|
| - num = num * 10 + (*cur - '0'); \
|
| - cur++; \
|
| - }
|
| -
|
| -/**
|
| - * PARSE_NUM:
|
| - * @num: the double to fill in
|
| - * @cur: an #xmlChar *
|
| - * @num_type: an integer flag
|
| - *
|
| - * Parses a float or integer and updates @num with the value. @cur is
|
| - * updated to point just after the number. If the number is a float,
|
| - * then it must have an integer part and a decimal part; @num_type will
|
| - * be set to 1. If there is no decimal part, @num_type is set to zero.
|
| - * In case of error, @num_type is set to -1, values of @num and
|
| - * @cur are undefined.
|
| - */
|
| -#define PARSE_NUM(num, cur, num_type) \
|
| - num = 0; \
|
| - PARSE_DIGITS(num, cur, num_type); \
|
| - if (!num_type && (*cur == '.')) { \
|
| - double mult = 1; \
|
| - cur++; \
|
| - if ((*cur < '0') || (*cur > '9')) \
|
| - num_type = -1; \
|
| - else \
|
| - num_type = 1; \
|
| - while ((*cur >= '0') && (*cur <= '9')) { \
|
| - mult /= 10; \
|
| - num += (*cur - '0') * mult; \
|
| - cur++; \
|
| - } \
|
| - }
|
| -
|
| -#ifdef WITH_TIME
|
| -/**
|
| - * exsltDateCurrent:
|
| - *
|
| - * Returns the current date and time.
|
| - */
|
| -static exsltDateValPtr
|
| -exsltDateCurrent (void)
|
| -{
|
| - struct tm localTm, gmTm;
|
| -#ifndef HAVE_GMTIME_R
|
| - struct tm *tb = NULL;
|
| -#endif
|
| - time_t secs;
|
| - int local_s, gm_s;
|
| - exsltDateValPtr ret;
|
| -#ifdef HAVE_ERRNO_H
|
| - char *source_date_epoch;
|
| -#endif /* HAVE_ERRNO_H */
|
| - int override = 0;
|
| -
|
| - ret = exsltDateCreateDate(XS_DATETIME);
|
| - if (ret == NULL)
|
| - return NULL;
|
| -
|
| -#ifdef HAVE_ERRNO_H
|
| - /*
|
| - * Allow the date and time to be set externally by an exported
|
| - * environment variable to enable reproducible builds.
|
| - */
|
| - source_date_epoch = getenv("SOURCE_DATE_EPOCH");
|
| - if (source_date_epoch) {
|
| - errno = 0;
|
| - secs = (time_t) strtol (source_date_epoch, NULL, 10);
|
| - if (errno == 0) {
|
| -#if HAVE_GMTIME_R
|
| - if (gmtime_r(&secs, &localTm) != NULL)
|
| - override = 1;
|
| -#else
|
| - tb = gmtime(&secs);
|
| - if (tb != NULL) {
|
| - localTm = *tb;
|
| - override = 1;
|
| - }
|
| -#endif
|
| - }
|
| - }
|
| -#endif /* HAVE_ERRNO_H */
|
| -
|
| - if (override == 0) {
|
| - /* get current time */
|
| - secs = time(NULL);
|
| -
|
| -#if HAVE_LOCALTIME_R
|
| - localtime_r(&secs, &localTm);
|
| -#else
|
| - localTm = *localtime(&secs);
|
| -#endif
|
| - }
|
| -
|
| - /* get real year, not years since 1900 */
|
| - ret->value.date.year = localTm.tm_year + 1900;
|
| -
|
| - ret->value.date.mon = localTm.tm_mon + 1;
|
| - ret->value.date.day = localTm.tm_mday;
|
| - ret->value.date.hour = localTm.tm_hour;
|
| - ret->value.date.min = localTm.tm_min;
|
| -
|
| - /* floating point seconds */
|
| - ret->value.date.sec = (double) localTm.tm_sec;
|
| -
|
| - /* determine the time zone offset from local to gm time */
|
| -#if HAVE_GMTIME_R
|
| - gmtime_r(&secs, &gmTm);
|
| -#else
|
| - tb = gmtime(&secs);
|
| - if (tb != NULL)
|
| - gmTm = *tb;
|
| -#endif
|
| - ret->value.date.tz_flag = 0;
|
| -#if 0
|
| - ret->value.date.tzo = (((ret->value.date.day * 1440) +
|
| - (ret->value.date.hour * 60) +
|
| - ret->value.date.min) -
|
| - ((gmTm.tm_mday * 1440) + (gmTm.tm_hour * 60) +
|
| - gmTm.tm_min));
|
| -#endif
|
| - local_s = localTm.tm_hour * SECS_PER_HOUR +
|
| - localTm.tm_min * SECS_PER_MIN +
|
| - localTm.tm_sec;
|
| -
|
| - gm_s = gmTm.tm_hour * SECS_PER_HOUR +
|
| - gmTm.tm_min * SECS_PER_MIN +
|
| - gmTm.tm_sec;
|
| -
|
| - if (localTm.tm_year < gmTm.tm_year) {
|
| - ret->value.date.tzo = -((SECS_PER_DAY - local_s) + gm_s)/60;
|
| - } else if (localTm.tm_year > gmTm.tm_year) {
|
| - ret->value.date.tzo = ((SECS_PER_DAY - gm_s) + local_s)/60;
|
| - } else if (localTm.tm_mon < gmTm.tm_mon) {
|
| - ret->value.date.tzo = -((SECS_PER_DAY - local_s) + gm_s)/60;
|
| - } else if (localTm.tm_mon > gmTm.tm_mon) {
|
| - ret->value.date.tzo = ((SECS_PER_DAY - gm_s) + local_s)/60;
|
| - } else if (localTm.tm_mday < gmTm.tm_mday) {
|
| - ret->value.date.tzo = -((SECS_PER_DAY - local_s) + gm_s)/60;
|
| - } else if (localTm.tm_mday > gmTm.tm_mday) {
|
| - ret->value.date.tzo = ((SECS_PER_DAY - gm_s) + local_s)/60;
|
| - } else {
|
| - ret->value.date.tzo = (local_s - gm_s)/60;
|
| - }
|
| -
|
| - return ret;
|
| -}
|
| -#endif
|
| -
|
| -/**
|
| - * exsltDateParse:
|
| - * @dateTime: string to analyze
|
| - *
|
| - * Parses a date/time string
|
| - *
|
| - * Returns a newly built #exsltDateValPtr of NULL in case of error
|
| - */
|
| -static exsltDateValPtr
|
| -exsltDateParse (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - int ret;
|
| - const xmlChar *cur = dateTime;
|
| -
|
| -#define RETURN_TYPE_IF_VALID(t) \
|
| - if (IS_TZO_CHAR(*cur)) { \
|
| - ret = _exsltDateParseTimeZone(&(dt->value.date), &cur); \
|
| - if (ret == 0) { \
|
| - if (*cur != 0) \
|
| - goto error; \
|
| - dt->type = t; \
|
| - return dt; \
|
| - } \
|
| - }
|
| -
|
| - if (dateTime == NULL)
|
| - return NULL;
|
| -
|
| - if ((*cur != '-') && (*cur < '0') && (*cur > '9'))
|
| - return NULL;
|
| -
|
| - dt = exsltDateCreateDate(EXSLT_UNKNOWN);
|
| - if (dt == NULL)
|
| - return NULL;
|
| -
|
| - if ((cur[0] == '-') && (cur[1] == '-')) {
|
| - /*
|
| - * It's an incomplete date (xs:gMonthDay, xs:gMonth or
|
| - * xs:gDay)
|
| - */
|
| - cur += 2;
|
| -
|
| - /* is it an xs:gDay? */
|
| - if (*cur == '-') {
|
| - ++cur;
|
| - ret = _exsltDateParseGDay(&(dt->value.date), &cur);
|
| - if (ret != 0)
|
| - goto error;
|
| -
|
| - RETURN_TYPE_IF_VALID(XS_GDAY);
|
| -
|
| - goto error;
|
| - }
|
| -
|
| - /*
|
| - * it should be an xs:gMonthDay or xs:gMonth
|
| - */
|
| - ret = _exsltDateParseGMonth(&(dt->value.date), &cur);
|
| - if (ret != 0)
|
| - goto error;
|
| -
|
| - if (*cur != '-')
|
| - goto error;
|
| - cur++;
|
| -
|
| - /* is it an xs:gMonth? */
|
| - if (*cur == '-') {
|
| - cur++;
|
| - RETURN_TYPE_IF_VALID(XS_GMONTH);
|
| - goto error;
|
| - }
|
| -
|
| - /* it should be an xs:gMonthDay */
|
| - ret = _exsltDateParseGDay(&(dt->value.date), &cur);
|
| - if (ret != 0)
|
| - goto error;
|
| -
|
| - RETURN_TYPE_IF_VALID(XS_GMONTHDAY);
|
| -
|
| - goto error;
|
| - }
|
| -
|
| - /*
|
| - * It's a right-truncated date or an xs:time.
|
| - * Try to parse an xs:time then fallback on right-truncated dates.
|
| - */
|
| - if ((*cur >= '0') && (*cur <= '9')) {
|
| - ret = _exsltDateParseTime(&(dt->value.date), &cur);
|
| - if (ret == 0) {
|
| - /* it's an xs:time */
|
| - RETURN_TYPE_IF_VALID(XS_TIME);
|
| - }
|
| - }
|
| -
|
| - /* fallback on date parsing */
|
| - cur = dateTime;
|
| -
|
| - ret = _exsltDateParseGYear(&(dt->value.date), &cur);
|
| - if (ret != 0)
|
| - goto error;
|
| -
|
| - /* is it an xs:gYear? */
|
| - RETURN_TYPE_IF_VALID(XS_GYEAR);
|
| -
|
| - if (*cur != '-')
|
| - goto error;
|
| - cur++;
|
| -
|
| - ret = _exsltDateParseGMonth(&(dt->value.date), &cur);
|
| - if (ret != 0)
|
| - goto error;
|
| -
|
| - /* is it an xs:gYearMonth? */
|
| - RETURN_TYPE_IF_VALID(XS_GYEARMONTH);
|
| -
|
| - if (*cur != '-')
|
| - goto error;
|
| - cur++;
|
| -
|
| - ret = _exsltDateParseGDay(&(dt->value.date), &cur);
|
| - if ((ret != 0) || !VALID_DATE((&(dt->value.date))))
|
| - goto error;
|
| -
|
| - /* is it an xs:date? */
|
| - RETURN_TYPE_IF_VALID(XS_DATE);
|
| -
|
| - if (*cur != 'T')
|
| - goto error;
|
| - cur++;
|
| -
|
| - /* it should be an xs:dateTime */
|
| - ret = _exsltDateParseTime(&(dt->value.date), &cur);
|
| - if (ret != 0)
|
| - goto error;
|
| -
|
| - ret = _exsltDateParseTimeZone(&(dt->value.date), &cur);
|
| - if ((ret != 0) || (*cur != 0) || !VALID_DATETIME((&(dt->value.date))))
|
| - goto error;
|
| -
|
| - dt->type = XS_DATETIME;
|
| -
|
| - return dt;
|
| -
|
| -error:
|
| - if (dt != NULL)
|
| - exsltDateFreeDate(dt);
|
| - return NULL;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateParseDuration:
|
| - * @duration: string to analyze
|
| - *
|
| - * Parses a duration string
|
| - *
|
| - * Returns a newly built #exsltDateValPtr of NULL in case of error
|
| - */
|
| -static exsltDateValPtr
|
| -exsltDateParseDuration (const xmlChar *duration)
|
| -{
|
| - const xmlChar *cur = duration;
|
| - exsltDateValPtr dur;
|
| - int isneg = 0;
|
| - unsigned int seq = 0;
|
| -
|
| - if (duration == NULL)
|
| - return NULL;
|
| -
|
| - if (*cur == '-') {
|
| - isneg = 1;
|
| - cur++;
|
| - }
|
| -
|
| - /* duration must start with 'P' (after sign) */
|
| - if (*cur++ != 'P')
|
| - return NULL;
|
| -
|
| - dur = exsltDateCreateDate(XS_DURATION);
|
| - if (dur == NULL)
|
| - return NULL;
|
| -
|
| - while (*cur != 0) {
|
| - double num;
|
| - int num_type = 0; /* -1 = invalid, 0 = int, 1 = floating */
|
| - const xmlChar desig[] = {'Y', 'M', 'D', 'H', 'M', 'S'};
|
| - const double multi[] = { 0.0, 0.0, 86400.0, 3600.0, 60.0, 1.0, 0.0};
|
| -
|
| - /* input string should be empty or invalid date/time item */
|
| - if (seq >= sizeof(desig))
|
| - goto error;
|
| -
|
| - /* T designator must be present for time items */
|
| - if (*cur == 'T') {
|
| - if (seq <= 3) {
|
| - seq = 3;
|
| - cur++;
|
| - } else
|
| - return NULL;
|
| - } else if (seq == 3)
|
| - goto error;
|
| -
|
| - /* parse the number portion of the item */
|
| - PARSE_NUM(num, cur, num_type);
|
| -
|
| - if ((num_type == -1) || (*cur == 0))
|
| - goto error;
|
| -
|
| - /* update duration based on item type */
|
| - while (seq < sizeof(desig)) {
|
| - if (*cur == desig[seq]) {
|
| -
|
| - /* verify numeric type; only seconds can be float */
|
| - if ((num_type != 0) && (seq < (sizeof(desig)-1)))
|
| - goto error;
|
| -
|
| - switch (seq) {
|
| - case 0:
|
| - dur->value.dur.mon = (long)num * 12;
|
| - break;
|
| - case 1:
|
| - dur->value.dur.mon += (long)num;
|
| - break;
|
| - default:
|
| - /* convert to seconds using multiplier */
|
| - dur->value.dur.sec += num * multi[seq];
|
| - seq++;
|
| - break;
|
| - }
|
| -
|
| - break; /* exit loop */
|
| - }
|
| - /* no date designators found? */
|
| - if (++seq == 3)
|
| - goto error;
|
| - }
|
| - cur++;
|
| - }
|
| -
|
| - if (isneg) {
|
| - dur->value.dur.mon = -dur->value.dur.mon;
|
| - dur->value.dur.day = -dur->value.dur.day;
|
| - dur->value.dur.sec = -dur->value.dur.sec;
|
| - }
|
| -
|
| -#ifdef DEBUG_EXSLT_DATE
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "Parsed duration %f\n", dur->value.dur.sec);
|
| -#endif
|
| -
|
| - return dur;
|
| -
|
| -error:
|
| - if (dur != NULL)
|
| - exsltDateFreeDate(dur);
|
| - return NULL;
|
| -}
|
| -
|
| -/**
|
| - * FORMAT_ITEM:
|
| - * @num: number to format
|
| - * @cur: current location to convert number
|
| - * @limit: max value
|
| - * @item: char designator
|
| - *
|
| - */
|
| -#define FORMAT_ITEM(num, cur, limit, item) \
|
| - if (num != 0) { \
|
| - long comp = (long)num / limit; \
|
| - if (comp != 0) { \
|
| - FORMAT_FLOAT((double)comp, cur, 0); \
|
| - *cur++ = item; \
|
| - num -= (double)(comp * limit); \
|
| - } \
|
| - }
|
| -
|
| -/**
|
| - * exsltDateFormatDuration:
|
| - * @dt: an #exsltDateValDurationPtr
|
| - *
|
| - * Formats @dt in xs:duration format.
|
| - *
|
| - * Returns a newly allocated string, or NULL in case of error
|
| - */
|
| -static xmlChar *
|
| -exsltDateFormatDuration (const exsltDateValDurationPtr dt)
|
| -{
|
| - xmlChar buf[100], *cur = buf;
|
| - double secs, days;
|
| - double years, months;
|
| -
|
| - if (dt == NULL)
|
| - return NULL;
|
| -
|
| - /* quick and dirty check */
|
| - if ((dt->sec == 0.0) && (dt->day == 0) && (dt->mon == 0))
|
| - return xmlStrdup((xmlChar*)"P0D");
|
| -
|
| - secs = dt->sec;
|
| - days = (double)dt->day;
|
| - years = (double)(dt->mon / 12);
|
| - months = (double)(dt->mon % 12);
|
| -
|
| - *cur = '\0';
|
| - if (secs < 0.0) {
|
| - secs = -secs;
|
| - *cur = '-';
|
| - }
|
| - if (days < 0) {
|
| - days = -days;
|
| - *cur = '-';
|
| - }
|
| - if (years < 0) {
|
| - years = -years;
|
| - *cur = '-';
|
| - }
|
| - if (months < 0) {
|
| - months = -months;
|
| - *cur = '-';
|
| - }
|
| - if (*cur == '-')
|
| - cur++;
|
| -
|
| - *cur++ = 'P';
|
| -
|
| - if (years != 0.0) {
|
| - FORMAT_ITEM(years, cur, 1, 'Y');
|
| - }
|
| -
|
| - if (months != 0.0) {
|
| - FORMAT_ITEM(months, cur, 1, 'M');
|
| - }
|
| -
|
| - if (secs >= SECS_PER_DAY) {
|
| - double tmp = floor(secs / SECS_PER_DAY);
|
| - days += tmp;
|
| - secs -= (tmp * SECS_PER_DAY);
|
| - }
|
| -
|
| - FORMAT_ITEM(days, cur, 1, 'D');
|
| - if (secs > 0.0) {
|
| - *cur++ = 'T';
|
| - }
|
| - FORMAT_ITEM(secs, cur, SECS_PER_HOUR, 'H');
|
| - FORMAT_ITEM(secs, cur, SECS_PER_MIN, 'M');
|
| - if (secs > 0.0) {
|
| - FORMAT_FLOAT(secs, cur, 0);
|
| - *cur++ = 'S';
|
| - }
|
| -
|
| - *cur = 0;
|
| -
|
| - return xmlStrdup(buf);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateFormatDateTime:
|
| - * @dt: an #exsltDateValDatePtr
|
| - *
|
| - * Formats @dt in xs:dateTime format.
|
| - *
|
| - * Returns a newly allocated string, or NULL in case of error
|
| - */
|
| -static xmlChar *
|
| -exsltDateFormatDateTime (const exsltDateValDatePtr dt)
|
| -{
|
| - xmlChar buf[100], *cur = buf;
|
| -
|
| - if ((dt == NULL) || !VALID_DATETIME(dt))
|
| - return NULL;
|
| -
|
| - FORMAT_DATE(dt, cur);
|
| - *cur = 'T';
|
| - cur++;
|
| - FORMAT_TIME(dt, cur);
|
| - FORMAT_TZ(dt->tzo, cur);
|
| - *cur = 0;
|
| -
|
| - return xmlStrdup(buf);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateFormatDate:
|
| - * @dt: an #exsltDateValDatePtr
|
| - *
|
| - * Formats @dt in xs:date format.
|
| - *
|
| - * Returns a newly allocated string, or NULL in case of error
|
| - */
|
| -static xmlChar *
|
| -exsltDateFormatDate (const exsltDateValDatePtr dt)
|
| -{
|
| - xmlChar buf[100], *cur = buf;
|
| -
|
| - if ((dt == NULL) || !VALID_DATETIME(dt))
|
| - return NULL;
|
| -
|
| - FORMAT_DATE(dt, cur);
|
| - if (dt->tz_flag || (dt->tzo != 0)) {
|
| - FORMAT_TZ(dt->tzo, cur);
|
| - }
|
| - *cur = 0;
|
| -
|
| - return xmlStrdup(buf);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateFormatTime:
|
| - * @dt: an #exsltDateValDatePtr
|
| - *
|
| - * Formats @dt in xs:time format.
|
| - *
|
| - * Returns a newly allocated string, or NULL in case of error
|
| - */
|
| -static xmlChar *
|
| -exsltDateFormatTime (const exsltDateValDatePtr dt)
|
| -{
|
| - xmlChar buf[100], *cur = buf;
|
| -
|
| - if ((dt == NULL) || !VALID_TIME(dt))
|
| - return NULL;
|
| -
|
| - FORMAT_TIME(dt, cur);
|
| - if (dt->tz_flag || (dt->tzo != 0)) {
|
| - FORMAT_TZ(dt->tzo, cur);
|
| - }
|
| - *cur = 0;
|
| -
|
| - return xmlStrdup(buf);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateFormat:
|
| - * @dt: an #exsltDateValPtr
|
| - *
|
| - * Formats @dt in the proper format.
|
| - * Note: xs:gmonth and xs:gday are not formatted as there are no
|
| - * routines that output them.
|
| - *
|
| - * Returns a newly allocated string, or NULL in case of error
|
| - */
|
| -static xmlChar *
|
| -exsltDateFormat (const exsltDateValPtr dt)
|
| -{
|
| -
|
| - if (dt == NULL)
|
| - return NULL;
|
| -
|
| - switch (dt->type) {
|
| - case XS_DURATION:
|
| - return exsltDateFormatDuration(&(dt->value.dur));
|
| - case XS_DATETIME:
|
| - return exsltDateFormatDateTime(&(dt->value.date));
|
| - case XS_DATE:
|
| - return exsltDateFormatDate(&(dt->value.date));
|
| - case XS_TIME:
|
| - return exsltDateFormatTime(&(dt->value.date));
|
| - default:
|
| - break;
|
| - }
|
| -
|
| - if (dt->type & XS_GYEAR) {
|
| - xmlChar buf[100], *cur = buf;
|
| -
|
| - FORMAT_GYEAR(dt->value.date.year, cur);
|
| - if (dt->type == XS_GYEARMONTH) {
|
| - *cur = '-';
|
| - cur++;
|
| - FORMAT_GMONTH(dt->value.date.mon, cur);
|
| - }
|
| -
|
| - if (dt->value.date.tz_flag || (dt->value.date.tzo != 0)) {
|
| - FORMAT_TZ(dt->value.date.tzo, cur);
|
| - }
|
| - *cur = 0;
|
| - return xmlStrdup(buf);
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -/**
|
| - * _exsltDateCastYMToDays:
|
| - * @dt: an #exsltDateValPtr
|
| - *
|
| - * Convert mon and year of @dt to total number of days. Take the
|
| - * number of years since (or before) 1 AD and add the number of leap
|
| - * years. This is a function because negative
|
| - * years must be handled a little differently and there is no zero year.
|
| - *
|
| - * Returns number of days.
|
| - */
|
| -static long
|
| -_exsltDateCastYMToDays (const exsltDateValPtr dt)
|
| -{
|
| - long ret;
|
| -
|
| - if (dt->value.date.year < 0)
|
| - ret = (dt->value.date.year * 365) +
|
| - (((dt->value.date.year+1)/4)-((dt->value.date.year+1)/100)+
|
| - ((dt->value.date.year+1)/400)) +
|
| - DAY_IN_YEAR(0, dt->value.date.mon, dt->value.date.year);
|
| - else
|
| - ret = ((dt->value.date.year-1) * 365) +
|
| - (((dt->value.date.year-1)/4)-((dt->value.date.year-1)/100)+
|
| - ((dt->value.date.year-1)/400)) +
|
| - DAY_IN_YEAR(0, dt->value.date.mon, dt->value.date.year);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * TIME_TO_NUMBER:
|
| - * @dt: an #exsltDateValPtr
|
| - *
|
| - * Calculates the number of seconds in the time portion of @dt.
|
| - *
|
| - * Returns seconds.
|
| - */
|
| -#define TIME_TO_NUMBER(dt) \
|
| - ((double)((dt->value.date.hour * SECS_PER_HOUR) + \
|
| - (dt->value.date.min * SECS_PER_MIN)) + dt->value.date.sec)
|
| -
|
| -/**
|
| - * exsltDateCastDateToNumber:
|
| - * @dt: an #exsltDateValPtr
|
| - *
|
| - * Calculates the number of seconds from year zero.
|
| - *
|
| - * Returns seconds from zero year.
|
| - */
|
| -static double
|
| -exsltDateCastDateToNumber (const exsltDateValPtr dt)
|
| -{
|
| - double ret = 0.0;
|
| -
|
| - if (dt == NULL)
|
| - return 0.0;
|
| -
|
| - if ((dt->type & XS_GYEAR) == XS_GYEAR) {
|
| - ret = (double)_exsltDateCastYMToDays(dt) * SECS_PER_DAY;
|
| - }
|
| -
|
| - /* add in days */
|
| - if (dt->type == XS_DURATION) {
|
| - ret += (double)dt->value.dur.day * SECS_PER_DAY;
|
| - ret += dt->value.dur.sec;
|
| - } else {
|
| - ret += (double)dt->value.date.day * SECS_PER_DAY;
|
| - /* add in time */
|
| - ret += TIME_TO_NUMBER(dt);
|
| - }
|
| -
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * _exsltDateTruncateDate:
|
| - * @dt: an #exsltDateValPtr
|
| - * @type: dateTime type to set to
|
| - *
|
| - * Set @dt to truncated @type.
|
| - *
|
| - * Returns 0 success, non-zero otherwise.
|
| - */
|
| -static int
|
| -_exsltDateTruncateDate (exsltDateValPtr dt, exsltDateType type)
|
| -{
|
| - if (dt == NULL)
|
| - return 1;
|
| -
|
| - if ((type & XS_TIME) != XS_TIME) {
|
| - dt->value.date.hour = 0;
|
| - dt->value.date.min = 0;
|
| - dt->value.date.sec = 0.0;
|
| - }
|
| -
|
| - if ((type & XS_GDAY) != XS_GDAY)
|
| - dt->value.date.day = 1;
|
| -
|
| - if ((type & XS_GMONTH) != XS_GMONTH)
|
| - dt->value.date.mon = 1;
|
| -
|
| - if ((type & XS_GYEAR) != XS_GYEAR)
|
| - dt->value.date.year = 0;
|
| -
|
| - dt->type = type;
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -/**
|
| - * _exsltDayInWeek:
|
| - * @yday: year day (1-366)
|
| - * @yr: year
|
| - *
|
| - * Determine the day-in-week from @yday and @yr. 0001-01-01 was
|
| - * a Monday so all other days are calculated from there. Take the
|
| - * number of years since (or before) add the number of leap years and
|
| - * the day-in-year and mod by 7. This is a function because negative
|
| - * years must be handled a little differently and there is no zero year.
|
| - *
|
| - * Returns day in week (Sunday = 0).
|
| - */
|
| -static long
|
| -_exsltDateDayInWeek(long yday, long yr)
|
| -{
|
| - long ret;
|
| -
|
| - if (yr < 0) {
|
| - ret = ((yr + (((yr+1)/4)-((yr+1)/100)+((yr+1)/400)) + yday) % 7);
|
| - if (ret < 0)
|
| - ret += 7;
|
| - } else
|
| - ret = (((yr-1) + (((yr-1)/4)-((yr-1)/100)+((yr-1)/400)) + yday) % 7);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/*
|
| - * macros for adding date/times and durations
|
| - */
|
| -#define FQUOTIENT(a,b) ((floor(((double)a/(double)b))))
|
| -#define MODULO(a,b) ((a - FQUOTIENT(a,b) * b))
|
| -#define FQUOTIENT_RANGE(a,low,high) (FQUOTIENT((a-low),(high-low)))
|
| -#define MODULO_RANGE(a,low,high) ((MODULO((a-low),(high-low)))+low)
|
| -
|
| -/**
|
| - * _exsltDateAdd:
|
| - * @dt: an #exsltDateValPtr
|
| - * @dur: an #exsltDateValPtr of type #XS_DURATION
|
| - *
|
| - * Compute a new date/time from @dt and @dur. This function assumes @dt
|
| - * is either #XS_DATETIME, #XS_DATE, #XS_GYEARMONTH, or #XS_GYEAR.
|
| - *
|
| - * Returns date/time pointer or NULL.
|
| - */
|
| -static exsltDateValPtr
|
| -_exsltDateAdd (exsltDateValPtr dt, exsltDateValPtr dur)
|
| -{
|
| - exsltDateValPtr ret;
|
| - long carry, tempdays, temp;
|
| - exsltDateValDatePtr r, d;
|
| - exsltDateValDurationPtr u;
|
| -
|
| - if ((dt == NULL) || (dur == NULL))
|
| - return NULL;
|
| -
|
| - ret = exsltDateCreateDate(dt->type);
|
| - if (ret == NULL)
|
| - return NULL;
|
| -
|
| - r = &(ret->value.date);
|
| - d = &(dt->value.date);
|
| - u = &(dur->value.dur);
|
| -
|
| - /* month */
|
| - carry = d->mon + u->mon;
|
| - r->mon = (unsigned int)MODULO_RANGE(carry, 1, 13);
|
| - carry = (long)FQUOTIENT_RANGE(carry, 1, 13);
|
| -
|
| - /* year (may be modified later) */
|
| - r->year = d->year + carry;
|
| - if (r->year == 0) {
|
| - if (d->year > 0)
|
| - r->year--;
|
| - else
|
| - r->year++;
|
| - }
|
| -
|
| - /* time zone */
|
| - r->tzo = d->tzo;
|
| - r->tz_flag = d->tz_flag;
|
| -
|
| - /* seconds */
|
| - r->sec = d->sec + u->sec;
|
| - carry = (long)FQUOTIENT((long)r->sec, 60);
|
| - if (r->sec != 0.0) {
|
| - r->sec = MODULO(r->sec, 60.0);
|
| - }
|
| -
|
| - /* minute */
|
| - carry += d->min;
|
| - r->min = (unsigned int)MODULO(carry, 60);
|
| - carry = (long)FQUOTIENT(carry, 60);
|
| -
|
| - /* hours */
|
| - carry += d->hour;
|
| - r->hour = (unsigned int)MODULO(carry, 24);
|
| - carry = (long)FQUOTIENT(carry, 24);
|
| -
|
| - /*
|
| - * days
|
| - * Note we use tempdays because the temporary values may need more
|
| - * than 5 bits
|
| - */
|
| - if ((VALID_YEAR(r->year)) && (VALID_MONTH(r->mon)) &&
|
| - (d->day > MAX_DAYINMONTH(r->year, r->mon)))
|
| - tempdays = MAX_DAYINMONTH(r->year, r->mon);
|
| - else if (d->day < 1)
|
| - tempdays = 1;
|
| - else
|
| - tempdays = d->day;
|
| -
|
| - tempdays += u->day + carry;
|
| -
|
| - while (1) {
|
| - if (tempdays < 1) {
|
| - long tmon = (long)MODULO_RANGE((int)r->mon-1, 1, 13);
|
| - long tyr = r->year + (long)FQUOTIENT_RANGE((int)r->mon-1, 1, 13);
|
| - if (tyr == 0)
|
| - tyr--;
|
| - /*
|
| - * Coverity detected an overrun in daysInMonth
|
| - * of size 12 at position 12 with index variable "((r)->mon - 1)"
|
| - */
|
| - if (tmon < 0)
|
| - tmon = 0;
|
| - if (tmon > 12)
|
| - tmon = 12;
|
| - tempdays += MAX_DAYINMONTH(tyr, tmon);
|
| - carry = -1;
|
| - } else if (tempdays > (long)MAX_DAYINMONTH(r->year, r->mon)) {
|
| - tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon);
|
| - carry = 1;
|
| - } else
|
| - break;
|
| -
|
| - temp = r->mon + carry;
|
| - r->mon = (unsigned int)MODULO_RANGE(temp, 1, 13);
|
| - r->year = r->year + (long)FQUOTIENT_RANGE(temp, 1, 13);
|
| - if (r->year == 0) {
|
| - if (temp < 1)
|
| - r->year--;
|
| - else
|
| - r->year++;
|
| - }
|
| - }
|
| -
|
| - r->day = tempdays;
|
| -
|
| - /*
|
| - * adjust the date/time type to the date values
|
| - */
|
| - if (ret->type != XS_DATETIME) {
|
| - if ((r->hour) || (r->min) || (r->sec))
|
| - ret->type = XS_DATETIME;
|
| - else if (ret->type != XS_DATE) {
|
| - if (r->day != 1)
|
| - ret->type = XS_DATE;
|
| - else if ((ret->type != XS_GYEARMONTH) && (r->mon != 1))
|
| - ret->type = XS_GYEARMONTH;
|
| - }
|
| - }
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * _exsltDateDifference:
|
| - * @x: an #exsltDateValPtr
|
| - * @y: an #exsltDateValPtr
|
| - * @flag: force difference in days
|
| - *
|
| - * Calculate the difference between @x and @y as a duration
|
| - * (i.e. y - x). If the @flag is set then even if the least specific
|
| - * format of @x or @y is xs:gYear or xs:gYearMonth.
|
| - *
|
| - * Returns date/time pointer or NULL.
|
| - */
|
| -static exsltDateValPtr
|
| -_exsltDateDifference (exsltDateValPtr x, exsltDateValPtr y, int flag)
|
| -{
|
| - exsltDateValPtr ret;
|
| -
|
| - if ((x == NULL) || (y == NULL))
|
| - return NULL;
|
| -
|
| - if (((x->type < XS_GYEAR) || (x->type > XS_DATETIME)) ||
|
| - ((y->type < XS_GYEAR) || (y->type > XS_DATETIME)))
|
| - return NULL;
|
| -
|
| - /*
|
| - * the operand with the most specific format must be converted to
|
| - * the same type as the operand with the least specific format.
|
| - */
|
| - if (x->type != y->type) {
|
| - if (x->type < y->type) {
|
| - _exsltDateTruncateDate(y, x->type);
|
| - } else {
|
| - _exsltDateTruncateDate(x, y->type);
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateCreateDate(XS_DURATION);
|
| - if (ret == NULL)
|
| - return NULL;
|
| -
|
| - if (((x->type == XS_GYEAR) || (x->type == XS_GYEARMONTH)) && (!flag)) {
|
| - /* compute the difference in months */
|
| - ret->value.dur.mon = ((y->value.date.year * 12) + y->value.date.mon) -
|
| - ((x->value.date.year * 12) + x->value.date.mon);
|
| - /* The above will give a wrong result if x and y are on different sides
|
| - of the September 1752. Resolution is welcome :-) */
|
| - } else {
|
| - ret->value.dur.day = _exsltDateCastYMToDays(y) -
|
| - _exsltDateCastYMToDays(x);
|
| - ret->value.dur.day += y->value.date.day - x->value.date.day;
|
| - ret->value.dur.sec = TIME_TO_NUMBER(y) - TIME_TO_NUMBER(x);
|
| - ret->value.dur.sec += (x->value.date.tzo - y->value.date.tzo) *
|
| - SECS_PER_MIN;
|
| - if (ret->value.dur.day > 0.0 && ret->value.dur.sec < 0.0) {
|
| - ret->value.dur.day -= 1;
|
| - ret->value.dur.sec = ret->value.dur.sec + SECS_PER_DAY;
|
| - } else if (ret->value.dur.day < 0.0 && ret->value.dur.sec > 0.0) {
|
| - ret->value.dur.day += 1;
|
| - ret->value.dur.sec = ret->value.dur.sec - SECS_PER_DAY;
|
| - }
|
| - }
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * _exsltDateAddDurCalc
|
| - * @ret: an exsltDateValPtr for the return value:
|
| - * @x: an exsltDateValPtr for the first operand
|
| - * @y: an exsltDateValPtr for the second operand
|
| - *
|
| - * Add two durations, catering for possible negative values.
|
| - * The sum is placed in @ret.
|
| - *
|
| - * Returns 1 for success, 0 if error detected.
|
| - */
|
| -static int
|
| -_exsltDateAddDurCalc (exsltDateValPtr ret, exsltDateValPtr x,
|
| - exsltDateValPtr y)
|
| -{
|
| - long carry;
|
| -
|
| - /* months */
|
| - ret->value.dur.mon = x->value.dur.mon + y->value.dur.mon;
|
| -
|
| - /* seconds */
|
| - ret->value.dur.sec = x->value.dur.sec + y->value.dur.sec;
|
| - carry = (long)FQUOTIENT(ret->value.dur.sec, SECS_PER_DAY);
|
| - if (ret->value.dur.sec != 0.0) {
|
| - ret->value.dur.sec = MODULO(ret->value.dur.sec, SECS_PER_DAY);
|
| - /*
|
| - * Our function MODULO always gives us a positive value, so
|
| - * if we end up with a "-ve" carry we need to adjust it
|
| - * appropriately (bug 154021)
|
| - */
|
| - if ((carry < 0) && (ret->value.dur.sec != 0)) {
|
| - /* change seconds to equiv negative modulus */
|
| - ret->value.dur.sec = ret->value.dur.sec - SECS_PER_DAY;
|
| - carry++;
|
| - }
|
| - }
|
| -
|
| - /* days */
|
| - ret->value.dur.day = x->value.dur.day + y->value.dur.day + carry;
|
| -
|
| - /*
|
| - * are the results indeterminate? i.e. how do you subtract days from
|
| - * months or years?
|
| - */
|
| - if ((((ret->value.dur.day > 0) || (ret->value.dur.sec > 0)) &&
|
| - (ret->value.dur.mon < 0)) ||
|
| - (((ret->value.dur.day < 0) || (ret->value.dur.sec < 0)) &&
|
| - (ret->value.dur.mon > 0))) {
|
| - return 0;
|
| - }
|
| - return 1;
|
| -}
|
| -
|
| -/**
|
| - * _exsltDateAddDuration:
|
| - * @x: an #exsltDateValPtr of type #XS_DURATION
|
| - * @y: an #exsltDateValPtr of type #XS_DURATION
|
| - *
|
| - * Compute a new duration from @x and @y.
|
| - *
|
| - * Returns date/time pointer or NULL.
|
| - */
|
| -static exsltDateValPtr
|
| -_exsltDateAddDuration (exsltDateValPtr x, exsltDateValPtr y)
|
| -{
|
| - exsltDateValPtr ret;
|
| -
|
| - if ((x == NULL) || (y == NULL))
|
| - return NULL;
|
| -
|
| - ret = exsltDateCreateDate(XS_DURATION);
|
| - if (ret == NULL)
|
| - return NULL;
|
| -
|
| - if (_exsltDateAddDurCalc(ret, x, y))
|
| - return ret;
|
| -
|
| - exsltDateFreeDate(ret);
|
| - return NULL;
|
| -}
|
| -
|
| -/****************************************************************
|
| - * *
|
| - * EXSLT - Dates and Times functions *
|
| - * *
|
| - ****************************************************************/
|
| -
|
| -/**
|
| - * exsltDateDateTime:
|
| - *
|
| - * Implements the EXSLT - Dates and Times date-time() function:
|
| - * string date:date-time()
|
| - *
|
| - * Returns the current date and time as a date/time string.
|
| - */
|
| -static xmlChar *
|
| -exsltDateDateTime (void)
|
| -{
|
| - xmlChar *ret = NULL;
|
| -#ifdef WITH_TIME
|
| - exsltDateValPtr cur;
|
| -
|
| - cur = exsltDateCurrent();
|
| - if (cur != NULL) {
|
| - ret = exsltDateFormatDateTime(&(cur->value.date));
|
| - exsltDateFreeDate(cur);
|
| - }
|
| -#endif
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDate:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times date() function:
|
| - * string date:date (string?)
|
| - *
|
| - * Returns the date specified in the date/time string given as the
|
| - * argument. If no argument is given, then the current local
|
| - * date/time, as returned by date:date-time is used as a default
|
| - * argument.
|
| - * The date/time string specified as an argument must be a string in
|
| - * the format defined as the lexical representation of either
|
| - * xs:dateTime or xs:date. If the argument is not in either of these
|
| - * formats, returns NULL.
|
| - */
|
| -static xmlChar *
|
| -exsltDateDate (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt = NULL;
|
| - xmlChar *ret = NULL;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return NULL;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return NULL;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE)) {
|
| - exsltDateFreeDate(dt);
|
| - return NULL;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateFormatDate(&(dt->value.date));
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateTime:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times time() function:
|
| - * string date:time (string?)
|
| - *
|
| - * Returns the time specified in the date/time string given as the
|
| - * argument. If no argument is given, then the current local
|
| - * date/time, as returned by date:date-time is used as a default
|
| - * argument.
|
| - * The date/time string specified as an argument must be a string in
|
| - * the format defined as the lexical representation of either
|
| - * xs:dateTime or xs:time. If the argument is not in either of these
|
| - * formats, returns NULL.
|
| - */
|
| -static xmlChar *
|
| -exsltDateTime (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt = NULL;
|
| - xmlChar *ret = NULL;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return NULL;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return NULL;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_TIME)) {
|
| - exsltDateFreeDate(dt);
|
| - return NULL;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateFormatTime(&(dt->value.date));
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateYear:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times year() function
|
| - * number date:year (string?)
|
| - * Returns the year of a date as a number. If no argument is given,
|
| - * then the current local date/time, as returned by date:date-time is
|
| - * used as a default argument.
|
| - * The date/time string specified as the first argument must be a
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gYear (CCYY)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateYear (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - double ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE) &&
|
| - (dt->type != XS_GYEARMONTH) && (dt->type != XS_GYEAR)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = (double) dt->value.date.year;
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateLeapYear:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times leap-year() function:
|
| - * boolean date:leap-yea (string?)
|
| - * Returns true if the year given in a date is a leap year. If no
|
| - * argument is given, then the current local date/time, as returned by
|
| - * date:date-time is used as a default argument.
|
| - * The date/time string specified as the first argument must be a
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gYear (CCYY)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static xmlXPathObjectPtr
|
| -exsltDateLeapYear (const xmlChar *dateTime)
|
| -{
|
| - double year;
|
| -
|
| - year = exsltDateYear(dateTime);
|
| - if (xmlXPathIsNaN(year))
|
| - return xmlXPathNewFloat(xmlXPathNAN);
|
| -
|
| - if (IS_LEAP((long)year))
|
| - return xmlXPathNewBoolean(1);
|
| -
|
| - return xmlXPathNewBoolean(0);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateMonthInYear:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times month-in-year() function:
|
| - * number date:month-in-year (string?)
|
| - * Returns the month of a date as a number. If no argument is given,
|
| - * then the current local date/time, as returned by date:date-time is
|
| - * used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gMonth (--MM--)
|
| - * - xs:gMonthDay (--MM-DD)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateMonthInYear (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - double ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE) &&
|
| - (dt->type != XS_GYEARMONTH) && (dt->type != XS_GMONTH) &&
|
| - (dt->type != XS_GMONTHDAY)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = (double) dt->value.date.mon;
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateMonthName:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Time month-name() function
|
| - * string date:month-name (string?)
|
| - * Returns the full name of the month of a date. If no argument is
|
| - * given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gMonth (--MM--)
|
| - * If the date/time string is not in one of these formats, then an
|
| - * empty string ('') is returned.
|
| - * The result is an English month name: one of 'January', 'February',
|
| - * 'March', 'April', 'May', 'June', 'July', 'August', 'September',
|
| - * 'October', 'November' or 'December'.
|
| - */
|
| -static const xmlChar *
|
| -exsltDateMonthName (const xmlChar *dateTime)
|
| -{
|
| - static const xmlChar monthNames[13][10] = {
|
| - { 0 },
|
| - { 'J', 'a', 'n', 'u', 'a', 'r', 'y', 0 },
|
| - { 'F', 'e', 'b', 'r', 'u', 'a', 'r', 'y', 0 },
|
| - { 'M', 'a', 'r', 'c', 'h', 0 },
|
| - { 'A', 'p', 'r', 'i', 'l', 0 },
|
| - { 'M', 'a', 'y', 0 },
|
| - { 'J', 'u', 'n', 'e', 0 },
|
| - { 'J', 'u', 'l', 'y', 0 },
|
| - { 'A', 'u', 'g', 'u', 's', 't', 0 },
|
| - { 'S', 'e', 'p', 't', 'e', 'm', 'b', 'e', 'r', 0 },
|
| - { 'O', 'c', 't', 'o', 'b', 'e', 'r', 0 },
|
| - { 'N', 'o', 'v', 'e', 'm', 'b', 'e', 'r', 0 },
|
| - { 'D', 'e', 'c', 'e', 'm', 'b', 'e', 'r', 0 }
|
| - };
|
| - int month;
|
| - month = (int) exsltDateMonthInYear(dateTime);
|
| - if (!VALID_MONTH(month))
|
| - month = 0;
|
| - return monthNames[month];
|
| -}
|
| -
|
| -/**
|
| - * exsltDateMonthAbbreviation:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Time month-abbreviation() function
|
| - * string date:month-abbreviation (string?)
|
| - * Returns the abbreviation of the month of a date. If no argument is
|
| - * given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gMonth (--MM--)
|
| - * If the date/time string is not in one of these formats, then an
|
| - * empty string ('') is returned.
|
| - * The result is an English month abbreviation: one of 'Jan', 'Feb',
|
| - * 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov' or
|
| - * 'Dec'.
|
| - */
|
| -static const xmlChar *
|
| -exsltDateMonthAbbreviation (const xmlChar *dateTime)
|
| -{
|
| - static const xmlChar monthAbbreviations[13][4] = {
|
| - { 0 },
|
| - { 'J', 'a', 'n', 0 },
|
| - { 'F', 'e', 'b', 0 },
|
| - { 'M', 'a', 'r', 0 },
|
| - { 'A', 'p', 'r', 0 },
|
| - { 'M', 'a', 'y', 0 },
|
| - { 'J', 'u', 'n', 0 },
|
| - { 'J', 'u', 'l', 0 },
|
| - { 'A', 'u', 'g', 0 },
|
| - { 'S', 'e', 'p', 0 },
|
| - { 'O', 'c', 't', 0 },
|
| - { 'N', 'o', 'v', 0 },
|
| - { 'D', 'e', 'c', 0 }
|
| - };
|
| - int month;
|
| - month = (int) exsltDateMonthInYear(dateTime);
|
| - if(!VALID_MONTH(month))
|
| - month = 0;
|
| - return monthAbbreviations[month];
|
| -}
|
| -
|
| -/**
|
| - * exsltDateWeekInYear:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times week-in-year() function
|
| - * number date:week-in-year (string?)
|
| - * Returns the week of the year as a number. If no argument is given,
|
| - * then the current local date/time, as returned by date:date-time is
|
| - * used as the default argument. For the purposes of numbering,
|
| - * counting follows ISO 8601: week 1 in a year is the week containing
|
| - * the first Thursday of the year, with new weeks beginning on a
|
| - * Monday.
|
| - * The date/time string specified as the argument is a right-truncated
|
| - * string in the format defined as the lexical representation of
|
| - * xs:dateTime in one of the formats defined in [XML Schema Part 2:
|
| - * Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateWeekInYear (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - long diy, diw, year, ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - diy = DAY_IN_YEAR(dt->value.date.day, dt->value.date.mon,
|
| - dt->value.date.year);
|
| -
|
| - /*
|
| - * Determine day-in-week (0=Sun, 1=Mon, etc.) then adjust so Monday
|
| - * is the first day-in-week
|
| - */
|
| - diw = (_exsltDateDayInWeek(diy, dt->value.date.year) + 6) % 7;
|
| -
|
| - /* ISO 8601 adjustment, 3 is Thu */
|
| - diy += (3 - diw);
|
| - if(diy < 1) {
|
| - year = dt->value.date.year - 1;
|
| - if(year == 0) year--;
|
| - diy = DAY_IN_YEAR(31, 12, year) + diy;
|
| - } else if (diy > (long)DAY_IN_YEAR(31, 12, dt->value.date.year)) {
|
| - diy -= DAY_IN_YEAR(31, 12, dt->value.date.year);
|
| - }
|
| -
|
| - ret = ((diy - 1) / 7) + 1;
|
| -
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return (double) ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateWeekInMonth:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times week-in-month() function
|
| - * number date:week-in-month (string?)
|
| - * The date:week-in-month function returns the week in a month of a
|
| - * date as a number. If no argument is given, then the current local
|
| - * date/time, as returned by date:date-time is used the default
|
| - * argument. For the purposes of numbering, the first day of the month
|
| - * is in week 1 and new weeks begin on a Monday (so the first and last
|
| - * weeks in a month will often have less than 7 days in them).
|
| - * The date/time string specified as the argument is a right-truncated
|
| - * string in the format defined as the lexical representation of
|
| - * xs:dateTime in one of the formats defined in [XML Schema Part 2:
|
| - * Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateWeekInMonth (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - long fdiy, fdiw, ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - fdiy = DAY_IN_YEAR(1, dt->value.date.mon, dt->value.date.year);
|
| - /*
|
| - * Determine day-in-week (0=Sun, 1=Mon, etc.) then adjust so Monday
|
| - * is the first day-in-week
|
| - */
|
| - fdiw = (_exsltDateDayInWeek(fdiy, dt->value.date.year) + 6) % 7;
|
| -
|
| - ret = ((dt->value.date.day + fdiw - 1) / 7) + 1;
|
| -
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return (double) ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDayInYear:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times day-in-year() function
|
| - * number date:day-in-year (string?)
|
| - * Returns the day of a date in a year as a number. If no argument is
|
| - * given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a right-truncated
|
| - * string in the format defined as the lexical representation of
|
| - * xs:dateTime in one of the formats defined in [XML Schema Part 2:
|
| - * Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateDayInYear (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - long ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = DAY_IN_YEAR(dt->value.date.day, dt->value.date.mon,
|
| - dt->value.date.year);
|
| -
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return (double) ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDayInMonth:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times day-in-month() function:
|
| - * number date:day-in-month (string?)
|
| - * Returns the day of a date as a number. If no argument is given,
|
| - * then the current local date/time, as returned by date:date-time is
|
| - * used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gMonthDay (--MM-DD)
|
| - * - xs:gDay (---DD)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateDayInMonth (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - double ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE) &&
|
| - (dt->type != XS_GMONTHDAY) && (dt->type != XS_GDAY)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = (double) dt->value.date.day;
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDayOfWeekInMonth:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times day-of-week-in-month() function:
|
| - * number date:day-of-week-in-month (string?)
|
| - * Returns the day-of-the-week in a month of a date as a number
|
| - * (e.g. 3 for the 3rd Tuesday in May). If no argument is
|
| - * given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a right-truncated
|
| - * string in the format defined as the lexical representation of
|
| - * xs:dateTime in one of the formats defined in [XML Schema Part 2:
|
| - * Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateDayOfWeekInMonth (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - long ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = ((dt->value.date.day -1) / 7) + 1;
|
| -
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return (double) ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDayInWeek:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times day-in-week() function:
|
| - * number date:day-in-week (string?)
|
| - * Returns the day of the week given in a date as a number. If no
|
| - * argument is given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - * The numbering of days of the week starts at 1 for Sunday, 2 for
|
| - * Monday and so on up to 7 for Saturday.
|
| - */
|
| -static double
|
| -exsltDateDayInWeek (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - long diy, ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_DATE)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - diy = DAY_IN_YEAR(dt->value.date.day, dt->value.date.mon,
|
| - dt->value.date.year);
|
| -
|
| - ret = _exsltDateDayInWeek(diy, dt->value.date.year) + 1;
|
| -
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return (double) ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDayName:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Time day-name() function
|
| - * string date:day-name (string?)
|
| - * Returns the full name of the day of the week of a date. If no
|
| - * argument is given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * If the date/time string is not in one of these formats, then an
|
| - * empty string ('') is returned.
|
| - * The result is an English day name: one of 'Sunday', 'Monday',
|
| - * 'Tuesday', 'Wednesday', 'Thursday' or 'Friday'.
|
| - */
|
| -static const xmlChar *
|
| -exsltDateDayName (const xmlChar *dateTime)
|
| -{
|
| - static const xmlChar dayNames[8][10] = {
|
| - { 0 },
|
| - { 'S', 'u', 'n', 'd', 'a', 'y', 0 },
|
| - { 'M', 'o', 'n', 'd', 'a', 'y', 0 },
|
| - { 'T', 'u', 'e', 's', 'd', 'a', 'y', 0 },
|
| - { 'W', 'e', 'd', 'n', 'e', 's', 'd', 'a', 'y', 0 },
|
| - { 'T', 'h', 'u', 'r', 's', 'd', 'a', 'y', 0 },
|
| - { 'F', 'r', 'i', 'd', 'a', 'y', 0 },
|
| - { 'S', 'a', 't', 'u', 'r', 'd', 'a', 'y', 0 }
|
| - };
|
| - int day;
|
| - day = (int) exsltDateDayInWeek(dateTime);
|
| - if((day < 1) || (day > 7))
|
| - day = 0;
|
| - return dayNames[day];
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDayAbbreviation:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Time day-abbreviation() function
|
| - * string date:day-abbreviation (string?)
|
| - * Returns the abbreviation of the day of the week of a date. If no
|
| - * argument is given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * If the date/time string is not in one of these formats, then an
|
| - * empty string ('') is returned.
|
| - * The result is a three-letter English day abbreviation: one of
|
| - * 'Sun', 'Mon', 'Tue', 'Wed', 'Thu' or 'Fri'.
|
| - */
|
| -static const xmlChar *
|
| -exsltDateDayAbbreviation (const xmlChar *dateTime)
|
| -{
|
| - static const xmlChar dayAbbreviations[8][4] = {
|
| - { 0 },
|
| - { 'S', 'u', 'n', 0 },
|
| - { 'M', 'o', 'n', 0 },
|
| - { 'T', 'u', 'e', 0 },
|
| - { 'W', 'e', 'd', 0 },
|
| - { 'T', 'h', 'u', 0 },
|
| - { 'F', 'r', 'i', 0 },
|
| - { 'S', 'a', 't', 0 }
|
| - };
|
| - int day;
|
| - day = (int) exsltDateDayInWeek(dateTime);
|
| - if((day < 1) || (day > 7))
|
| - day = 0;
|
| - return dayAbbreviations[day];
|
| -}
|
| -
|
| -/**
|
| - * exsltDateHourInDay:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times day-in-month() function:
|
| - * number date:day-in-month (string?)
|
| - * Returns the hour of the day as a number. If no argument is given,
|
| - * then the current local date/time, as returned by date:date-time is
|
| - * used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:time (hh:mm:ss)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateHourInDay (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - double ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_TIME)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = (double) dt->value.date.hour;
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateMinuteInHour:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times day-in-month() function:
|
| - * number date:day-in-month (string?)
|
| - * Returns the minute of the hour as a number. If no argument is
|
| - * given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:time (hh:mm:ss)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - */
|
| -static double
|
| -exsltDateMinuteInHour (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - double ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_TIME)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = (double) dt->value.date.min;
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateSecondInMinute:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times second-in-minute() function:
|
| - * number date:day-in-month (string?)
|
| - * Returns the second of the minute as a number. If no argument is
|
| - * given, then the current local date/time, as returned by
|
| - * date:date-time is used the default argument.
|
| - * The date/time string specified as the argument is a left or
|
| - * right-truncated string in the format defined as the lexical
|
| - * representation of xs:dateTime in one of the formats defined in [XML
|
| - * Schema Part 2: Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:time (hh:mm:ss)
|
| - * If the date/time string is not in one of these formats, then NaN is
|
| - * returned.
|
| - *
|
| - * Returns the second or NaN.
|
| - */
|
| -static double
|
| -exsltDateSecondInMinute (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - double ret;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParse(dateTime);
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| - if ((dt->type != XS_DATETIME) && (dt->type != XS_TIME)) {
|
| - exsltDateFreeDate(dt);
|
| - return xmlXPathNAN;
|
| - }
|
| - }
|
| -
|
| - ret = dt->value.date.sec;
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateAdd:
|
| - * @xstr: date/time string
|
| - * @ystr: date/time string
|
| - *
|
| - * Implements the date:add (string,string) function which returns the
|
| - * date/time * resulting from adding a duration to a date/time.
|
| - * The first argument (@xstr) must be right-truncated date/time
|
| - * strings in one of the formats defined in [XML Schema Part 2:
|
| - * Datatypes]. The permitted formats are as follows:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gYear (CCYY)
|
| - * The second argument (@ystr) is a string in the format defined for
|
| - * xs:duration in [3.2.6 duration] of [XML Schema Part 2: Datatypes].
|
| - * The return value is a right-truncated date/time strings in one of
|
| - * the formats defined in [XML Schema Part 2: Datatypes] and listed
|
| - * above. This value is calculated using the algorithm described in
|
| - * [Appendix E Adding durations to dateTimes] of [XML Schema Part 2:
|
| - * Datatypes].
|
| -
|
| - * Returns date/time string or NULL.
|
| - */
|
| -static xmlChar *
|
| -exsltDateAdd (const xmlChar *xstr, const xmlChar *ystr)
|
| -{
|
| - exsltDateValPtr dt, dur, res;
|
| - xmlChar *ret;
|
| -
|
| - if ((xstr == NULL) || (ystr == NULL))
|
| - return NULL;
|
| -
|
| - dt = exsltDateParse(xstr);
|
| - if (dt == NULL)
|
| - return NULL;
|
| - else if ((dt->type < XS_GYEAR) || (dt->type > XS_DATETIME)) {
|
| - exsltDateFreeDate(dt);
|
| - return NULL;
|
| - }
|
| -
|
| - dur = exsltDateParseDuration(ystr);
|
| - if (dur == NULL) {
|
| - exsltDateFreeDate(dt);
|
| - return NULL;
|
| - }
|
| -
|
| - res = _exsltDateAdd(dt, dur);
|
| -
|
| - exsltDateFreeDate(dt);
|
| - exsltDateFreeDate(dur);
|
| -
|
| - if (res == NULL)
|
| - return NULL;
|
| -
|
| - ret = exsltDateFormat(res);
|
| - exsltDateFreeDate(res);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateAddDuration:
|
| - * @xstr: first duration string
|
| - * @ystr: second duration string
|
| - *
|
| - * Implements the date:add-duration (string,string) function which returns
|
| - * the duration resulting from adding two durations together.
|
| - * Both arguments are strings in the format defined for xs:duration
|
| - * in [3.2.6 duration] of [XML Schema Part 2: Datatypes]. If either
|
| - * argument is not in this format, the function returns an empty string
|
| - * ('').
|
| - * The return value is a string in the format defined for xs:duration
|
| - * in [3.2.6 duration] of [XML Schema Part 2: Datatypes].
|
| - * The durations can usually be added by summing the numbers given for
|
| - * each of the components in the durations. However, if the durations
|
| - * are differently signed, then this sometimes results in durations
|
| - * that are impossible to express in this syntax (e.g. 'P1M' + '-P1D').
|
| - * In these cases, the function returns an empty string ('').
|
| - *
|
| - * Returns duration string or NULL.
|
| - */
|
| -static xmlChar *
|
| -exsltDateAddDuration (const xmlChar *xstr, const xmlChar *ystr)
|
| -{
|
| - exsltDateValPtr x, y, res;
|
| - xmlChar *ret;
|
| -
|
| - if ((xstr == NULL) || (ystr == NULL))
|
| - return NULL;
|
| -
|
| - x = exsltDateParseDuration(xstr);
|
| - if (x == NULL)
|
| - return NULL;
|
| -
|
| - y = exsltDateParseDuration(ystr);
|
| - if (y == NULL) {
|
| - exsltDateFreeDate(x);
|
| - return NULL;
|
| - }
|
| -
|
| - res = _exsltDateAddDuration(x, y);
|
| -
|
| - exsltDateFreeDate(x);
|
| - exsltDateFreeDate(y);
|
| -
|
| - if (res == NULL)
|
| - return NULL;
|
| -
|
| - ret = exsltDateFormatDuration(&(res->value.dur));
|
| - exsltDateFreeDate(res);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateSumFunction:
|
| - * @ns: a node set of duration strings
|
| - *
|
| - * The date:sum function adds a set of durations together.
|
| - * The string values of the nodes in the node set passed as an argument
|
| - * are interpreted as durations and added together as if using the
|
| - * date:add-duration function. (from exslt.org)
|
| - *
|
| - * The return value is a string in the format defined for xs:duration
|
| - * in [3.2.6 duration] of [XML Schema Part 2: Datatypes].
|
| - * The durations can usually be added by summing the numbers given for
|
| - * each of the components in the durations. However, if the durations
|
| - * are differently signed, then this sometimes results in durations
|
| - * that are impossible to express in this syntax (e.g. 'P1M' + '-P1D').
|
| - * In these cases, the function returns an empty string ('').
|
| - *
|
| - * Returns duration string or NULL.
|
| - */
|
| -static void
|
| -exsltDateSumFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlNodeSetPtr ns;
|
| - void *user = NULL;
|
| - xmlChar *tmp;
|
| - exsltDateValPtr x, total;
|
| - xmlChar *ret;
|
| - int i;
|
| -
|
| - if (nargs != 1) {
|
| - xmlXPathSetArityError (ctxt);
|
| - return;
|
| - }
|
| -
|
| - /* We need to delay the freeing of value->user */
|
| - if ((ctxt->value != NULL) && ctxt->value->boolval != 0) {
|
| - user = ctxt->value->user;
|
| - ctxt->value->boolval = 0;
|
| - ctxt->value->user = NULL;
|
| - }
|
| -
|
| - ns = xmlXPathPopNodeSet (ctxt);
|
| - if (xmlXPathCheckError (ctxt))
|
| - return;
|
| -
|
| - if ((ns == NULL) || (ns->nodeNr == 0)) {
|
| - xmlXPathReturnEmptyString (ctxt);
|
| - if (ns != NULL)
|
| - xmlXPathFreeNodeSet (ns);
|
| - return;
|
| - }
|
| -
|
| - total = exsltDateCreateDate (XS_DURATION);
|
| - if (total == NULL) {
|
| - xmlXPathFreeNodeSet (ns);
|
| - return;
|
| - }
|
| -
|
| - for (i = 0; i < ns->nodeNr; i++) {
|
| - int result;
|
| - tmp = xmlXPathCastNodeToString (ns->nodeTab[i]);
|
| - if (tmp == NULL) {
|
| - xmlXPathFreeNodeSet (ns);
|
| - exsltDateFreeDate (total);
|
| - return;
|
| - }
|
| -
|
| - x = exsltDateParseDuration (tmp);
|
| - if (x == NULL) {
|
| - xmlFree (tmp);
|
| - exsltDateFreeDate (total);
|
| - xmlXPathFreeNodeSet (ns);
|
| - xmlXPathReturnEmptyString (ctxt);
|
| - return;
|
| - }
|
| -
|
| - result = _exsltDateAddDurCalc(total, total, x);
|
| -
|
| - exsltDateFreeDate (x);
|
| - xmlFree (tmp);
|
| - if (!result) {
|
| - exsltDateFreeDate (total);
|
| - xmlXPathFreeNodeSet (ns);
|
| - xmlXPathReturnEmptyString (ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateFormatDuration (&(total->value.dur));
|
| - exsltDateFreeDate (total);
|
| -
|
| - xmlXPathFreeNodeSet (ns);
|
| - if (user != NULL)
|
| - xmlFreeNodeList ((xmlNodePtr) user);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString (ctxt);
|
| - else
|
| - xmlXPathReturnString (ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateSeconds:
|
| - * @dateTime: a date/time string
|
| - *
|
| - * Implements the EXSLT - Dates and Times seconds() function:
|
| - * number date:seconds(string?)
|
| - * The date:seconds function returns the number of seconds specified
|
| - * by the argument string. If no argument is given, then the current
|
| - * local date/time, as returned by exsltDateCurrent() is used as the
|
| - * default argument. If the date/time string is a xs:duration, then the
|
| - * years and months must be zero (or not present). Parsing a duration
|
| - * converts the fields to seconds. If the date/time string is not a
|
| - * duration (and not null), then the legal formats are:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gYear (CCYY)
|
| - * In these cases the difference between the @dateTime and
|
| - * 1970-01-01T00:00:00Z is calculated and converted to seconds.
|
| - *
|
| - * Note that there was some confusion over whether "difference" meant
|
| - * that a dateTime of 1970-01-01T00:00:01Z should be a positive one or
|
| - * a negative one. After correspondence with exslt.org, it was determined
|
| - * that the intent of the specification was to have it positive. The
|
| - * coding was modified in July 2003 to reflect this.
|
| - *
|
| - * Returns seconds or Nan.
|
| - */
|
| -static double
|
| -exsltDateSeconds (const xmlChar *dateTime)
|
| -{
|
| - exsltDateValPtr dt;
|
| - double ret = xmlXPathNAN;
|
| -
|
| - if (dateTime == NULL) {
|
| -#ifdef WITH_TIME
|
| - dt = exsltDateCurrent();
|
| - if (dt == NULL)
|
| -#endif
|
| - return xmlXPathNAN;
|
| - } else {
|
| - dt = exsltDateParseDuration(dateTime);
|
| - if (dt == NULL)
|
| - dt = exsltDateParse(dateTime);
|
| - }
|
| -
|
| - if (dt == NULL)
|
| - return xmlXPathNAN;
|
| -
|
| - if ((dt->type <= XS_DATETIME) && (dt->type >= XS_GYEAR)) {
|
| - exsltDateValPtr y, dur;
|
| -
|
| - /*
|
| - * compute the difference between the given (or current) date
|
| - * and epoch date
|
| - */
|
| - y = exsltDateCreateDate(XS_DATETIME);
|
| - if (y != NULL) {
|
| - y->value.date.year = 1970;
|
| - y->value.date.mon = 1;
|
| - y->value.date.day = 1;
|
| - y->value.date.tz_flag = 1;
|
| -
|
| - dur = _exsltDateDifference(y, dt, 1);
|
| - if (dur != NULL) {
|
| - ret = exsltDateCastDateToNumber(dur);
|
| - exsltDateFreeDate(dur);
|
| - }
|
| - exsltDateFreeDate(y);
|
| - }
|
| -
|
| - } else if ((dt->type == XS_DURATION) && (dt->value.dur.mon == 0))
|
| - ret = exsltDateCastDateToNumber(dt);
|
| -
|
| - exsltDateFreeDate(dt);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDifference:
|
| - * @xstr: date/time string
|
| - * @ystr: date/time string
|
| - *
|
| - * Implements the date:difference (string,string) function which returns
|
| - * the duration between the first date and the second date. If the first
|
| - * date occurs before the second date, then the result is a positive
|
| - * duration; if it occurs after the second date, the result is a
|
| - * negative duration. The two dates must both be right-truncated
|
| - * date/time strings in one of the formats defined in [XML Schema Part
|
| - * 2: Datatypes]. The date/time with the most specific format (i.e. the
|
| - * least truncation) is converted into the same format as the date with
|
| - * the least specific format (i.e. the most truncation). The permitted
|
| - * formats are as follows, from most specific to least specific:
|
| - * - xs:dateTime (CCYY-MM-DDThh:mm:ss)
|
| - * - xs:date (CCYY-MM-DD)
|
| - * - xs:gYearMonth (CCYY-MM)
|
| - * - xs:gYear (CCYY)
|
| - * If either of the arguments is not in one of these formats,
|
| - * date:difference returns the empty string ('').
|
| - * The difference between the date/times is returned as a string in the
|
| - * format defined for xs:duration in [3.2.6 duration] of [XML Schema
|
| - * Part 2: Datatypes].
|
| - * If the date/time string with the least specific format is in either
|
| - * xs:gYearMonth or xs:gYear format, then the number of days, hours,
|
| - * minutes and seconds in the duration string must be equal to zero.
|
| - * (The format of the string will be PnYnM.) The number of months
|
| - * specified in the duration must be less than 12.
|
| - * Otherwise, the number of years and months in the duration string
|
| - * must be equal to zero. (The format of the string will be
|
| - * PnDTnHnMnS.) The number of seconds specified in the duration string
|
| - * must be less than 60; the number of minutes must be less than 60;
|
| - * the number of hours must be less than 24.
|
| - *
|
| - * Returns duration string or NULL.
|
| - */
|
| -static xmlChar *
|
| -exsltDateDifference (const xmlChar *xstr, const xmlChar *ystr)
|
| -{
|
| - exsltDateValPtr x, y, dur;
|
| - xmlChar *ret = NULL;
|
| -
|
| - if ((xstr == NULL) || (ystr == NULL))
|
| - return NULL;
|
| -
|
| - x = exsltDateParse(xstr);
|
| - if (x == NULL)
|
| - return NULL;
|
| -
|
| - y = exsltDateParse(ystr);
|
| - if (y == NULL) {
|
| - exsltDateFreeDate(x);
|
| - return NULL;
|
| - }
|
| -
|
| - if (((x->type < XS_GYEAR) || (x->type > XS_DATETIME)) ||
|
| - ((y->type < XS_GYEAR) || (y->type > XS_DATETIME))) {
|
| - exsltDateFreeDate(x);
|
| - exsltDateFreeDate(y);
|
| - return NULL;
|
| - }
|
| -
|
| - dur = _exsltDateDifference(x, y, 0);
|
| -
|
| - exsltDateFreeDate(x);
|
| - exsltDateFreeDate(y);
|
| -
|
| - if (dur == NULL)
|
| - return NULL;
|
| -
|
| - ret = exsltDateFormatDuration(&(dur->value.dur));
|
| - exsltDateFreeDate(dur);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDuration:
|
| - * @number: a xmlChar string
|
| - *
|
| - * Implements the The date:duration function returns a duration string
|
| - * representing the number of seconds specified by the argument string.
|
| - * If no argument is given, then the result of calling date:seconds
|
| - * without any arguments is used as a default argument.
|
| - * The duration is returned as a string in the format defined for
|
| - * xs:duration in [3.2.6 duration] of [XML Schema Part 2: Datatypes].
|
| - * The number of years and months in the duration string must be equal
|
| - * to zero. (The format of the string will be PnDTnHnMnS.) The number
|
| - * of seconds specified in the duration string must be less than 60;
|
| - * the number of minutes must be less than 60; the number of hours must
|
| - * be less than 24.
|
| - * If the argument is Infinity, -Infinity or NaN, then date:duration
|
| - * returns an empty string ('').
|
| - *
|
| - * Returns duration string or NULL.
|
| - */
|
| -static xmlChar *
|
| -exsltDateDuration (const xmlChar *number)
|
| -{
|
| - exsltDateValPtr dur;
|
| - double secs;
|
| - xmlChar *ret;
|
| -
|
| - if (number == NULL)
|
| - secs = exsltDateSeconds(number);
|
| - else
|
| - secs = xmlXPathCastStringToNumber(number);
|
| -
|
| - if ((xmlXPathIsNaN(secs)) || (xmlXPathIsInf(secs)))
|
| - return NULL;
|
| -
|
| - dur = exsltDateCreateDate(XS_DURATION);
|
| - if (dur == NULL)
|
| - return NULL;
|
| -
|
| - dur->value.dur.sec = secs;
|
| -
|
| - ret = exsltDateFormatDuration(&(dur->value.dur));
|
| - exsltDateFreeDate(dur);
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -/****************************************************************
|
| - * *
|
| - * Wrappers for use by the XPath engine *
|
| - * *
|
| - ****************************************************************/
|
| -
|
| -#ifdef WITH_TIME
|
| -/**
|
| - * exsltDateDateTimeFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDateTime() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateDateTimeFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *ret;
|
| -
|
| - if (nargs != 0) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - ret = exsltDateDateTime();
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, ret);
|
| -}
|
| -#endif
|
| -
|
| -/**
|
| - * exsltDateDateFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDate() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateDateFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *ret, *dt = NULL;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateDate(dt);
|
| -
|
| - if (ret == NULL) {
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "{http://exslt.org/dates-and-times}date: "
|
| - "invalid date or format %s\n", dt);
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - } else {
|
| - xmlXPathReturnString(ctxt, ret);
|
| - }
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateTimeFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateTime() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateTimeFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *ret, *dt = NULL;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateTime(dt);
|
| -
|
| - if (ret == NULL) {
|
| - xsltGenericDebug(xsltGenericDebugContext,
|
| - "{http://exslt.org/dates-and-times}time: "
|
| - "invalid date or format %s\n", dt);
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - } else {
|
| - xmlXPathReturnString(ctxt, ret);
|
| - }
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateYearFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateYear() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateYearFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *dt = NULL;
|
| - double ret;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateYear(dt);
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -
|
| - xmlXPathReturnNumber(ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateLeapYearFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateLeapYear() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateLeapYearFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *dt = NULL;
|
| - xmlXPathObjectPtr ret;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateLeapYear(dt);
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -
|
| - valuePush(ctxt, ret);
|
| -}
|
| -
|
| -#define X_IN_Y(x, y) \
|
| -static void \
|
| -exsltDate##x##In##y##Function (xmlXPathParserContextPtr ctxt, \
|
| - int nargs) { \
|
| - xmlChar *dt = NULL; \
|
| - double ret; \
|
| - \
|
| - if ((nargs < 0) || (nargs > 1)) { \
|
| - xmlXPathSetArityError(ctxt); \
|
| - return; \
|
| - } \
|
| - \
|
| - if (nargs == 1) { \
|
| - dt = xmlXPathPopString(ctxt); \
|
| - if (xmlXPathCheckError(ctxt)) { \
|
| - xmlXPathSetTypeError(ctxt); \
|
| - return; \
|
| - } \
|
| - } \
|
| - \
|
| - ret = exsltDate##x##In##y(dt); \
|
| - \
|
| - if (dt != NULL) \
|
| - xmlFree(dt); \
|
| - \
|
| - xmlXPathReturnNumber(ctxt, ret); \
|
| -}
|
| -
|
| -/**
|
| - * exsltDateMonthInYearFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateMonthInYear() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Month,Year)
|
| -
|
| -/**
|
| - * exsltDateMonthNameFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateMonthName() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateMonthNameFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *dt = NULL;
|
| - const xmlChar *ret;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateMonthName(dt);
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, xmlStrdup(ret));
|
| -}
|
| -
|
| -/**
|
| - * exsltDateMonthAbbreviationFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateMonthAbbreviation() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateMonthAbbreviationFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *dt = NULL;
|
| - const xmlChar *ret;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateMonthAbbreviation(dt);
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, xmlStrdup(ret));
|
| -}
|
| -
|
| -/**
|
| - * exsltDateWeekInYearFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateWeekInYear() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Week,Year)
|
| -
|
| -/**
|
| - * exsltDateWeekInMonthFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateWeekInMonthYear() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Week,Month)
|
| -
|
| -/**
|
| - * exsltDateDayInYearFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDayInYear() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Day,Year)
|
| -
|
| -/**
|
| - * exsltDateDayInMonthFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDayInMonth() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Day,Month)
|
| -
|
| -/**
|
| - * exsltDateDayOfWeekInMonthFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDayOfWeekInMonth() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(DayOfWeek,Month)
|
| -
|
| -/**
|
| - * exsltDateDayInWeekFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDayInWeek() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Day,Week)
|
| -
|
| -/**
|
| - * exsltDateDayNameFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDayName() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateDayNameFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *dt = NULL;
|
| - const xmlChar *ret;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateDayName(dt);
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, xmlStrdup(ret));
|
| -}
|
| -
|
| -/**
|
| - * exsltDateMonthDayFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDayAbbreviation() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateDayAbbreviationFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *dt = NULL;
|
| - const xmlChar *ret;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - dt = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateDayAbbreviation(dt);
|
| -
|
| - if (dt != NULL)
|
| - xmlFree(dt);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, xmlStrdup(ret));
|
| -}
|
| -
|
| -
|
| -/**
|
| - * exsltDateHourInDayFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateHourInDay() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Hour,Day)
|
| -
|
| -/**
|
| - * exsltDateMinuteInHourFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateMinuteInHour() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Minute,Hour)
|
| -
|
| -/**
|
| - * exsltDateSecondInMinuteFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateSecondInMinute() for use by the XPath engine.
|
| - */
|
| -X_IN_Y(Second,Minute)
|
| -
|
| -/**
|
| - * exsltDateSecondsFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateSeconds() for use by the XPath engine.
|
| - */
|
| -static void
|
| -exsltDateSecondsFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *str = NULL;
|
| - double ret;
|
| -
|
| - if (nargs > 1) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - str = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateSeconds(str);
|
| - if (str != NULL)
|
| - xmlFree(str);
|
| -
|
| - xmlXPathReturnNumber(ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateAddFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Wraps exsltDateAdd() for use by the XPath processor.
|
| - */
|
| -static void
|
| -exsltDateAddFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *ret, *xstr, *ystr;
|
| -
|
| - if (nargs != 2) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| - ystr = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt))
|
| - return;
|
| -
|
| - xstr = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlFree(ystr);
|
| - return;
|
| - }
|
| -
|
| - ret = exsltDateAdd(xstr, ystr);
|
| -
|
| - xmlFree(ystr);
|
| - xmlFree(xstr);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateAddDurationFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Wraps exsltDateAddDuration() for use by the XPath processor.
|
| - */
|
| -static void
|
| -exsltDateAddDurationFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *ret, *xstr, *ystr;
|
| -
|
| - if (nargs != 2) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| - ystr = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt))
|
| - return;
|
| -
|
| - xstr = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlFree(ystr);
|
| - return;
|
| - }
|
| -
|
| - ret = exsltDateAddDuration(xstr, ystr);
|
| -
|
| - xmlFree(ystr);
|
| - xmlFree(xstr);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDifferenceFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Wraps exsltDateDifference() for use by the XPath processor.
|
| - */
|
| -static void
|
| -exsltDateDifferenceFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *ret, *xstr, *ystr;
|
| -
|
| - if (nargs != 2) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| - ystr = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt))
|
| - return;
|
| -
|
| - xstr = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlFree(ystr);
|
| - return;
|
| - }
|
| -
|
| - ret = exsltDateDifference(xstr, ystr);
|
| -
|
| - xmlFree(ystr);
|
| - xmlFree(xstr);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateDurationFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs : the number of arguments
|
| - *
|
| - * Wraps exsltDateDuration() for use by the XPath engine
|
| - */
|
| -static void
|
| -exsltDateDurationFunction (xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xmlChar *ret;
|
| - xmlChar *number = NULL;
|
| -
|
| - if ((nargs < 0) || (nargs > 1)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 1) {
|
| - number = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - ret = exsltDateDuration(number);
|
| -
|
| - if (number != NULL)
|
| - xmlFree(number);
|
| -
|
| - if (ret == NULL)
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - else
|
| - xmlXPathReturnString(ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateRegister:
|
| - *
|
| - * Registers the EXSLT - Dates and Times module
|
| - */
|
| -void
|
| -exsltDateRegister (void)
|
| -{
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "add",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateAddFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "add-duration",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateAddDurationFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "date",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDateFunction);
|
| -#ifdef WITH_TIME
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "date-time",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDateTimeFunction);
|
| -#endif
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "day-abbreviation",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayAbbreviationFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "day-in-month",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayInMonthFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "day-in-week",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayInWeekFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "day-in-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayInYearFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "day-name",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayNameFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "day-of-week-in-month",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayOfWeekInMonthFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "difference",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDifferenceFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "duration",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDurationFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "hour-in-day",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateHourInDayFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "leap-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateLeapYearFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "minute-in-hour",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMinuteInHourFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "month-abbreviation",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMonthAbbreviationFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "month-in-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMonthInYearFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "month-name",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMonthNameFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "second-in-minute",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateSecondInMinuteFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "seconds",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateSecondsFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "sum",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateSumFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "time",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateTimeFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "week-in-month",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateWeekInMonthFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "week-in-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateWeekInYearFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateYearFunction);
|
| -}
|
| -
|
| -/**
|
| - * exsltDateXpathCtxtRegister:
|
| - *
|
| - * Registers the EXSLT - Dates and Times module for use outside XSLT
|
| - */
|
| -int
|
| -exsltDateXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix)
|
| -{
|
| - if (ctxt
|
| - && prefix
|
| - && !xmlXPathRegisterNs(ctxt,
|
| - prefix,
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "add",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateAddFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "add-duration",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateAddDurationFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "date",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDateFunction)
|
| -#ifdef WITH_TIME
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "date-time",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDateTimeFunction)
|
| -#endif
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "day-abbreviation",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayAbbreviationFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "day-in-month",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayInMonthFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "day-in-week",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayInWeekFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "day-in-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayInYearFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "day-name",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayNameFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "day-of-week-in-month",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDayOfWeekInMonthFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "difference",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDifferenceFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "duration",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateDurationFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "hour-in-day",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateHourInDayFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "leap-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateLeapYearFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "minute-in-hour",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMinuteInHourFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "month-abbreviation",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMonthAbbreviationFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "month-in-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMonthInYearFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "month-name",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateMonthNameFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "second-in-minute",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateSecondInMinuteFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "seconds",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateSecondsFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "sum",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateSumFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "time",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateTimeFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "week-in-month",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateWeekInMonthFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "week-in-year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateWeekInYearFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "year",
|
| - (const xmlChar *) EXSLT_DATE_NAMESPACE,
|
| - exsltDateYearFunction)) {
|
| - return 0;
|
| - }
|
| - return -1;
|
| -}
|
|
|