diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2017-05-03 17:01:52 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2017-05-03 17:01:52 (GMT) |
commit | 105878ba114ead35390129e837493fa519e4c3e3 (patch) | |
tree | 4a53b0c0f87e6a5dd452e9469cd68e4b1cbab1dd /libxslt/libexslt | |
parent | ff3be2710b869b933ec568e4b71fddaf63e64d92 (diff) | |
download | blt-105878ba114ead35390129e837493fa519e4c3e3.zip blt-105878ba114ead35390129e837493fa519e4c3e3.tar.gz blt-105878ba114ead35390129e837493fa519e4c3e3.tar.bz2 |
rm libxslt
Diffstat (limited to 'libxslt/libexslt')
-rw-r--r-- | libxslt/libexslt/Makefile.am | 35 | ||||
-rw-r--r-- | libxslt/libexslt/common.c | 137 | ||||
-rw-r--r-- | libxslt/libexslt/crypto.c | 806 | ||||
-rw-r--r-- | libxslt/libexslt/date.c | 3911 | ||||
-rw-r--r-- | libxslt/libexslt/dynamic.c | 304 | ||||
-rw-r--r-- | libxslt/libexslt/exslt.c | 40 | ||||
-rw-r--r-- | libxslt/libexslt/exslt.h | 102 | ||||
-rw-r--r-- | libxslt/libexslt/exsltconfig.h.in | 73 | ||||
-rw-r--r-- | libxslt/libexslt/exsltexports.h | 140 | ||||
-rw-r--r-- | libxslt/libexslt/functions.c | 795 | ||||
-rw-r--r-- | libxslt/libexslt/libexslt.3 | 270 | ||||
-rw-r--r-- | libxslt/libexslt/libexslt.h | 29 | ||||
-rw-r--r-- | libxslt/libexslt/math.c | 1202 | ||||
-rw-r--r-- | libxslt/libexslt/saxon.c | 313 | ||||
-rw-r--r-- | libxslt/libexslt/sets.c | 334 | ||||
-rw-r--r-- | libxslt/libexslt/strings.c | 847 |
16 files changed, 0 insertions, 9338 deletions
diff --git a/libxslt/libexslt/Makefile.am b/libxslt/libexslt/Makefile.am deleted file mode 100644 index 1cf5138..0000000 --- a/libxslt/libexslt/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/libxslt -I$(top_srcdir)/libexslt \ - -I$(top_builddir) -I$(top_builddir)/libxslt \ - -I$(top_builddir)/libexslt - -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBXML_CFLAGS) - -lib_LTLIBRARIES = libexslt.la - -exsltincdir = $(includedir)/libexslt - -exsltinc_HEADERS = \ - exslt.h \ - exsltexports.h -nodist_exsltinc_HEADERS = \ - exsltconfig.h - -libexslt_la_SOURCES = \ - exslt.c \ - common.c \ - crypto.c \ - math.c \ - sets.c \ - functions.c \ - strings.c \ - date.c \ - saxon.c \ - libexslt.h \ - dynamic.c - -libexslt_la_LIBADD = $(top_builddir)/libxslt/libxslt.la $(EXTRA_LIBS) $(LIBGCRYPT_LIBS) -libexslt_la_LDFLAGS = $(WIN32_EXTRA_LDFLAGS) -version-info $(LIBEXSLT_VERSION_INFO) - -man_MANS = libexslt.3 - -EXTRA_DIST = $(man_MANS) diff --git a/libxslt/libexslt/common.c b/libxslt/libexslt/common.c deleted file mode 100644 index 451a60d..0000000 --- a/libxslt/libexslt/common.c +++ /dev/null @@ -1,137 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#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 <libxslt/transform.h> -#include <libxslt/extra.h> -#include <libxslt/preproc.h> - -#include "exslt.h" - -static void -exsltNodeSetFunction (xmlXPathParserContextPtr ctxt, int nargs) { - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - if (xmlXPathStackIsNodeSet (ctxt)) { - xsltFunctionNodeSet (ctxt, nargs); - return; - } else { - xmlDocPtr fragment; - xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); - xmlNodePtr txt; - xmlChar *strval; - xmlXPathObjectPtr obj; - /* - * SPEC EXSLT: - * "You can also use this function to turn a string into a text - * node, which is helpful if you want to pass a string to a - * function that only accepts a node-set." - */ - fragment = xsltCreateRVT(tctxt); - if (fragment == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltNodeSetFunction: Failed to create a tree fragment.\n"); - tctxt->state = XSLT_STATE_STOPPED; - return; - } - xsltRegisterLocalRVT(tctxt, fragment); - - strval = xmlXPathPopString (ctxt); - - txt = xmlNewDocText (fragment, strval); - xmlAddChild((xmlNodePtr) fragment, txt); - obj = xmlXPathNewNodeSet(txt); - if (obj == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltNodeSetFunction: Failed to create a node set object.\n"); - tctxt->state = XSLT_STATE_STOPPED; - } else { - /* - * Mark it as a function result in order to avoid garbage - * collecting of tree fragments - */ - xsltExtensionInstructionResultRegister(tctxt, obj); - } - if (strval != NULL) - xmlFree (strval); - - valuePush (ctxt, obj); - } -} - -static void -exsltObjectTypeFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr obj, ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - - obj = valuePop(ctxt); - - switch (obj->type) { - case XPATH_STRING: - ret = xmlXPathNewCString("string"); - break; - case XPATH_NUMBER: - ret = xmlXPathNewCString("number"); - break; - case XPATH_BOOLEAN: - ret = xmlXPathNewCString("boolean"); - break; - case XPATH_NODESET: - ret = xmlXPathNewCString("node-set"); - break; - case XPATH_XSLT_TREE: - ret = xmlXPathNewCString("RTF"); - break; - case XPATH_USERS: - ret = xmlXPathNewCString("external"); - break; - default: - xsltGenericError(xsltGenericErrorContext, - "object-type() invalid arg\n"); - ctxt->error = XPATH_INVALID_TYPE; - xmlXPathFreeObject(obj); - return; - } - xmlXPathFreeObject(obj); - valuePush(ctxt, ret); -} - - -/** - * exsltCommonRegister: - * - * Registers the EXSLT - Common module - */ - -void -exsltCommonRegister (void) { - xsltRegisterExtModuleFunction((const xmlChar *) "node-set", - EXSLT_COMMON_NAMESPACE, - exsltNodeSetFunction); - xsltRegisterExtModuleFunction((const xmlChar *) "object-type", - EXSLT_COMMON_NAMESPACE, - exsltObjectTypeFunction); - xsltRegisterExtModuleElement((const xmlChar *) "document", - EXSLT_COMMON_NAMESPACE, - (xsltPreComputeFunction) xsltDocumentComp, - (xsltTransformFunction) xsltDocumentElem); -} diff --git a/libxslt/libexslt/crypto.c b/libxslt/libexslt/crypto.c deleted file mode 100644 index e13db8b..0000000 --- a/libxslt/libexslt/crypto.c +++ /dev/null @@ -1,806 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#endif - -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> -#include <libxml/parser.h> -#include <libxml/encoding.h> -#include <libxml/uri.h> - -#include <libxslt/xsltconfig.h> -#include <libxslt/xsltutils.h> -#include <libxslt/xsltInternals.h> -#include <libxslt/extensions.h> - -#include "exslt.h" - -#ifdef EXSLT_CRYPTO_ENABLED - -#define HASH_DIGEST_LENGTH 32 -#define MD5_DIGEST_LENGTH 16 -#define SHA1_DIGEST_LENGTH 20 - -/* gcrypt rc4 can do 256 bit keys, but cryptoapi limit - seems to be 128 for the default provider */ -#define RC4_KEY_LENGTH 128 - -/* The following routines have been declared static - this should be - reviewed to consider whether we want to expose them to the API - exsltCryptoBin2Hex - exsltCryptoHex2Bin - exsltCryptoGcryptInit - exsltCryptoGcryptHash - exsltCryptoGcryptRc4Encrypt - exsltCryptoGcryptRC4Decrypt -*/ - -/** - * exsltCryptoBin2Hex: - * @bin: binary blob to convert - * @binlen: length of binary blob - * @hex: buffer to store hex version of blob - * @hexlen: length of buffer to store hex version of blob - * - * Helper function which encodes a binary blob as hex. - */ -static void -exsltCryptoBin2Hex (const unsigned char *bin, int binlen, - unsigned char *hex, int hexlen) { - static const char bin2hex[] = { '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' - }; - - unsigned char lo, hi; - int i, pos; - for (i = 0, pos = 0; (i < binlen && pos < hexlen); i++) { - lo = bin[i] & 0xf; - hi = bin[i] >> 4; - hex[pos++] = bin2hex[hi]; - hex[pos++] = bin2hex[lo]; - } - - hex[pos] = '\0'; -} - -/** - * exsltCryptoHex2Bin: - * @hex: hex version of blob to convert - * @hexlen: length of hex buffer - * @bin: destination binary buffer - * @binlen: length of binary buffer - * - * Helper function which decodes a hex blob to binary - */ -static int -exsltCryptoHex2Bin (const unsigned char *hex, int hexlen, - unsigned char *bin, int binlen) { - int i = 0, j = 0; - unsigned char lo, hi, result, tmp; - - while (i < hexlen && j < binlen) { - hi = lo = 0; - - tmp = hex[i++]; - if (tmp >= '0' && tmp <= '9') - hi = tmp - '0'; - else if (tmp >= 'a' && tmp <= 'f') - hi = 10 + (tmp - 'a'); - - tmp = hex[i++]; - if (tmp >= '0' && tmp <= '9') - lo = tmp - '0'; - else if (tmp >= 'a' && tmp <= 'f') - lo = 10 + (tmp - 'a'); - - result = hi << 4; - result += lo; - bin[j++] = result; - } - - return j; -} - -#if defined(WIN32) - -#define HAVE_CRYPTO -#define PLATFORM_HASH exsltCryptoCryptoApiHash -#define PLATFORM_RC4_ENCRYPT exsltCryptoCryptoApiRc4Encrypt -#define PLATFORM_RC4_DECRYPT exsltCryptoCryptoApiRc4Decrypt -#define PLATFORM_MD4 CALG_MD4 -#define PLATFORM_MD5 CALG_MD5 -#define PLATFORM_SHA1 CALG_SHA1 - -#include <windows.h> -#include <wincrypt.h> -#pragma comment(lib, "advapi32.lib") - -static void -exsltCryptoCryptoApiReportError (xmlXPathParserContextPtr ctxt, - int line) { - LPVOID lpMsgBuf; - DWORD dw = GetLastError (); - - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) & lpMsgBuf, 0, NULL); - - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL, - "exslt:crypto error (line %d). %s", line, - lpMsgBuf); - LocalFree (lpMsgBuf); -} - -static HCRYPTHASH -exsltCryptoCryptoApiCreateHash (xmlXPathParserContextPtr ctxt, - HCRYPTPROV hCryptProv, ALG_ID algorithm, - const char *msg, unsigned int msglen, - char *dest, unsigned int destlen) -{ - HCRYPTHASH hHash = 0; - DWORD dwHashLen = destlen; - - if (!CryptCreateHash (hCryptProv, algorithm, 0, 0, &hHash)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - return 0; - } - - if (!CryptHashData (hHash, (const BYTE *) msg, msglen, 0)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - goto fail; - } - - if (!CryptGetHashParam (hHash, HP_HASHVAL, dest, &dwHashLen, 0)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - goto fail; - } - - fail: - return hHash; -} - -/** - * exsltCryptoCryptoApiHash: - * @ctxt: an XPath parser context - * @algorithm: hashing algorithm to use - * @msg: text to be hashed - * @msglen: length of text to be hashed - * @dest: buffer to place hash result - * - * Helper function which hashes a message using MD4, MD5, or SHA1. - * Uses Win32 CryptoAPI. - */ -static void -exsltCryptoCryptoApiHash (xmlXPathParserContextPtr ctxt, - ALG_ID algorithm, const char *msg, - unsigned long msglen, - char dest[HASH_DIGEST_LENGTH]) { - HCRYPTPROV hCryptProv; - HCRYPTHASH hHash; - - if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - return; - } - - hHash = exsltCryptoCryptoApiCreateHash (ctxt, hCryptProv, - algorithm, msg, msglen, - dest, HASH_DIGEST_LENGTH); - if (0 != hHash) { - CryptDestroyHash (hHash); - } - - CryptReleaseContext (hCryptProv, 0); -} - -static void -exsltCryptoCryptoApiRc4Encrypt (xmlXPathParserContextPtr ctxt, - const unsigned char *key, - const unsigned char *msg, int msglen, - unsigned char *dest, int destlen) { - HCRYPTPROV hCryptProv; - HCRYPTKEY hKey; - HCRYPTHASH hHash; - DWORD dwDataLen; - unsigned char hash[HASH_DIGEST_LENGTH]; - - if (msglen > destlen) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto : internal error exsltCryptoCryptoApiRc4Encrypt dest buffer too small.\n"); - return; - } - - if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - return; - } - - hHash = exsltCryptoCryptoApiCreateHash (ctxt, hCryptProv, - CALG_SHA1, key, - RC4_KEY_LENGTH, hash, - HASH_DIGEST_LENGTH); - - if (!CryptDeriveKey - (hCryptProv, CALG_RC4, hHash, 0x00800000, &hKey)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - goto fail; - } -/* Now encrypt data. */ - dwDataLen = msglen; - memcpy (dest, msg, msglen); - if (!CryptEncrypt (hKey, 0, TRUE, 0, dest, &dwDataLen, msglen)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - goto fail; - } - - fail: - if (0 != hHash) { - CryptDestroyHash (hHash); - } - - CryptDestroyKey (hKey); - CryptReleaseContext (hCryptProv, 0); -} - -static void -exsltCryptoCryptoApiRc4Decrypt (xmlXPathParserContextPtr ctxt, - const unsigned char *key, - const unsigned char *msg, int msglen, - unsigned char *dest, int destlen) { - HCRYPTPROV hCryptProv; - HCRYPTKEY hKey; - HCRYPTHASH hHash; - DWORD dwDataLen; - unsigned char hash[HASH_DIGEST_LENGTH]; - - if (msglen > destlen) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto : internal error exsltCryptoCryptoApiRc4Encrypt dest buffer too small.\n"); - return; - } - - if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - return; - } - - hHash = exsltCryptoCryptoApiCreateHash (ctxt, hCryptProv, - CALG_SHA1, key, - RC4_KEY_LENGTH, hash, - HASH_DIGEST_LENGTH); - - if (!CryptDeriveKey - (hCryptProv, CALG_RC4, hHash, 0x00800000, &hKey)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - goto fail; - } -/* Now encrypt data. */ - dwDataLen = msglen; - memcpy (dest, msg, msglen); - if (!CryptDecrypt (hKey, 0, TRUE, 0, dest, &dwDataLen)) { - exsltCryptoCryptoApiReportError (ctxt, __LINE__); - goto fail; - } - - fail: - if (0 != hHash) { - CryptDestroyHash (hHash); - } - - CryptDestroyKey (hKey); - CryptReleaseContext (hCryptProv, 0); -} - -#endif /* defined(WIN32) */ - -#if defined(HAVE_GCRYPT) - -#define HAVE_CRYPTO -#define PLATFORM_HASH exsltCryptoGcryptHash -#define PLATFORM_RC4_ENCRYPT exsltCryptoGcryptRc4Encrypt -#define PLATFORM_RC4_DECRYPT exsltCryptoGcryptRc4Decrypt -#define PLATFORM_MD4 GCRY_MD_MD4 -#define PLATFORM_MD5 GCRY_MD_MD5 -#define PLATFORM_SHA1 GCRY_MD_SHA1 - -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> /* needed by gcrypt.h 4 Jul 04 */ -#endif -#include <gcrypt.h> - -static void -exsltCryptoGcryptInit (void) { - static int gcrypt_init; - xmlLockLibrary (); - - if (!gcrypt_init) { -/* The function `gcry_check_version' must be called before any other - function in the library, because it initializes the thread support - subsystem in Libgcrypt. To achieve this in all generality, it is - necessary to synchronize the call to this function with all other calls - to functions in the library, using the synchronization mechanisms - available in your thread library. (from gcrypt.info) -*/ - gcry_check_version (GCRYPT_VERSION); - gcrypt_init = 1; - } - - xmlUnlockLibrary (); -} - -/** - * exsltCryptoGcryptHash: - * @ctxt: an XPath parser context - * @algorithm: hashing algorithm to use - * @msg: text to be hashed - * @msglen: length of text to be hashed - * @dest: buffer to place hash result - * - * Helper function which hashes a message using MD4, MD5, or SHA1. - * using gcrypt - */ -static void -exsltCryptoGcryptHash (xmlXPathParserContextPtr ctxt ATTRIBUTE_UNUSED, -/* changed the enum to int */ - int algorithm, const char *msg, - unsigned long msglen, - char dest[HASH_DIGEST_LENGTH]) { - exsltCryptoGcryptInit (); - gcry_md_hash_buffer (algorithm, dest, msg, msglen); -} - -static void -exsltCryptoGcryptRc4Encrypt (xmlXPathParserContextPtr ctxt, - const unsigned char *key, - const unsigned char *msg, int msglen, - unsigned char *dest, int destlen) { - gcry_cipher_hd_t cipher; - gcry_error_t rc = 0; - - exsltCryptoGcryptInit (); - - rc = gcry_cipher_open (&cipher, GCRY_CIPHER_ARCFOUR, - GCRY_CIPHER_MODE_STREAM, 0); - if (rc) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto internal error %s (gcry_cipher_open)\n", - gcry_strerror (rc)); - } - - rc = gcry_cipher_setkey (cipher, key, RC4_KEY_LENGTH); - if (rc) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto internal error %s (gcry_cipher_setkey)\n", - gcry_strerror (rc)); - } - - rc = gcry_cipher_encrypt (cipher, (unsigned char *) dest, destlen, - (const unsigned char *) msg, msglen); - if (rc) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto internal error %s (gcry_cipher_encrypt)\n", - gcry_strerror (rc)); - } - - gcry_cipher_close (cipher); -} - -static void -exsltCryptoGcryptRc4Decrypt (xmlXPathParserContextPtr ctxt, - const unsigned char *key, - const unsigned char *msg, int msglen, - unsigned char *dest, int destlen) { - gcry_cipher_hd_t cipher; - gcry_error_t rc = 0; - - exsltCryptoGcryptInit (); - - rc = gcry_cipher_open (&cipher, GCRY_CIPHER_ARCFOUR, - GCRY_CIPHER_MODE_STREAM, 0); - if (rc) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto internal error %s (gcry_cipher_open)\n", - gcry_strerror (rc)); - } - - rc = gcry_cipher_setkey (cipher, key, RC4_KEY_LENGTH); - if (rc) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto internal error %s (gcry_cipher_setkey)\n", - gcry_strerror (rc)); - } - - rc = gcry_cipher_decrypt (cipher, (unsigned char *) dest, destlen, - (const unsigned char *) msg, msglen); - if (rc) { - xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, - NULL, - "exslt:crypto internal error %s (gcry_cipher_decrypt)\n", - gcry_strerror (rc)); - } - - gcry_cipher_close (cipher); -} - -#endif /* defined(HAVE_GCRYPT) */ - -#if defined(HAVE_CRYPTO) - -/** - * exsltCryptoPopString: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Helper function which checks for and returns first string argument and its - * length in bytes. - */ -static int -exsltCryptoPopString (xmlXPathParserContextPtr ctxt, int nargs, - xmlChar ** str) { - - int str_len = 0; - - if ((nargs < 1) || (nargs > 2)) { - xmlXPathSetArityError (ctxt); - return 0; - } - - *str = xmlXPathPopString (ctxt); - str_len = xmlStrlen (*str); - - if (str_len == 0) { - xmlXPathReturnEmptyString (ctxt); - xmlFree (*str); - return 0; - } - - return str_len; -} - -/** - * exsltCryptoMd4Function: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * computes the md4 hash of a string and returns as hex - */ -static void -exsltCryptoMd4Function (xmlXPathParserContextPtr ctxt, int nargs) { - - int str_len = 0; - xmlChar *str = NULL, *ret = NULL; - unsigned char hash[HASH_DIGEST_LENGTH]; - unsigned char hex[MD5_DIGEST_LENGTH * 2 + 1]; - - str_len = exsltCryptoPopString (ctxt, nargs, &str); - if (str_len == 0) - return; - - PLATFORM_HASH (ctxt, PLATFORM_MD4, (const char *) str, str_len, - (char *) hash); - exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1); - - ret = xmlStrdup ((xmlChar *) hex); - xmlXPathReturnString (ctxt, ret); - - if (str != NULL) - xmlFree (str); -} - -/** - * exsltCryptoMd5Function: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * computes the md5 hash of a string and returns as hex - */ -static void -exsltCryptoMd5Function (xmlXPathParserContextPtr ctxt, int nargs) { - - int str_len = 0; - xmlChar *str = NULL, *ret = NULL; - unsigned char hash[HASH_DIGEST_LENGTH]; - unsigned char hex[MD5_DIGEST_LENGTH * 2 + 1]; - - str_len = exsltCryptoPopString (ctxt, nargs, &str); - if (str_len == 0) - return; - - PLATFORM_HASH (ctxt, PLATFORM_MD5, (const char *) str, str_len, - (char *) hash); - exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1); - - ret = xmlStrdup ((xmlChar *) hex); - xmlXPathReturnString (ctxt, ret); - - if (str != NULL) - xmlFree (str); -} - -/** - * exsltCryptoSha1Function: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * computes the sha1 hash of a string and returns as hex - */ -static void -exsltCryptoSha1Function (xmlXPathParserContextPtr ctxt, int nargs) { - - int str_len = 0; - xmlChar *str = NULL, *ret = NULL; - unsigned char hash[HASH_DIGEST_LENGTH]; - unsigned char hex[SHA1_DIGEST_LENGTH * 2 + 1]; - - str_len = exsltCryptoPopString (ctxt, nargs, &str); - if (str_len == 0) - return; - - PLATFORM_HASH (ctxt, PLATFORM_SHA1, (const char *) str, str_len, - (char *) hash); - exsltCryptoBin2Hex (hash, sizeof (hash) - 1, hex, sizeof (hex) - 1); - - ret = xmlStrdup ((xmlChar *) hex); - xmlXPathReturnString (ctxt, ret); - - if (str != NULL) - xmlFree (str); -} - -/** - * exsltCryptoRc4EncryptFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * computes the sha1 hash of a string and returns as hex - */ -static void -exsltCryptoRc4EncryptFunction (xmlXPathParserContextPtr ctxt, int nargs) { - - int key_len = 0; - int str_len = 0, bin_len = 0, hex_len = 0; - xmlChar *key = NULL, *str = NULL, *padkey = NULL; - xmlChar *bin = NULL, *hex = NULL; - xsltTransformContextPtr tctxt = NULL; - - if (nargs != 2) { - xmlXPathSetArityError (ctxt); - return; - } - tctxt = xsltXPathGetTransformContext(ctxt); - - str = xmlXPathPopString (ctxt); - str_len = xmlStrlen (str); - - if (str_len == 0) { - xmlXPathReturnEmptyString (ctxt); - xmlFree (str); - return; - } - - key = xmlXPathPopString (ctxt); - key_len = xmlStrlen (key); - - if (key_len == 0) { - xmlXPathReturnEmptyString (ctxt); - xmlFree (key); - xmlFree (str); - return; - } - - padkey = xmlMallocAtomic (RC4_KEY_LENGTH + 1); - if (padkey == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: Failed to allocate padkey\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - memset(padkey, 0, RC4_KEY_LENGTH + 1); - - if ((key_len > RC4_KEY_LENGTH) || (key_len < 0)) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: key size too long or key broken\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - memcpy (padkey, key, key_len); - -/* encrypt it */ - bin_len = str_len; - bin = xmlStrdup (str); - if (bin == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: Failed to allocate string\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - PLATFORM_RC4_ENCRYPT (ctxt, padkey, str, str_len, bin, bin_len); - -/* encode it */ - hex_len = str_len * 2 + 1; - hex = xmlMallocAtomic (hex_len); - if (hex == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: Failed to allocate result\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - - exsltCryptoBin2Hex (bin, str_len, hex, hex_len); - xmlXPathReturnString (ctxt, hex); - -done: - if (key != NULL) - xmlFree (key); - if (str != NULL) - xmlFree (str); - if (padkey != NULL) - xmlFree (padkey); - if (bin != NULL) - xmlFree (bin); -} - -/** - * exsltCryptoRc4DecryptFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * computes the sha1 hash of a string and returns as hex - */ -static void -exsltCryptoRc4DecryptFunction (xmlXPathParserContextPtr ctxt, int nargs) { - - int key_len = 0; - int str_len = 0, bin_len = 0, ret_len = 0; - xmlChar *key = NULL, *str = NULL, *padkey = NULL, *bin = - NULL, *ret = NULL; - xsltTransformContextPtr tctxt = NULL; - - if (nargs != 2) { - xmlXPathSetArityError (ctxt); - return; - } - tctxt = xsltXPathGetTransformContext(ctxt); - - str = xmlXPathPopString (ctxt); - str_len = xmlStrlen (str); - - if (str_len == 0) { - xmlXPathReturnEmptyString (ctxt); - xmlFree (str); - return; - } - - key = xmlXPathPopString (ctxt); - key_len = xmlStrlen (key); - - if (key_len == 0) { - xmlXPathReturnEmptyString (ctxt); - xmlFree (key); - xmlFree (str); - return; - } - - padkey = xmlMallocAtomic (RC4_KEY_LENGTH + 1); - if (padkey == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: Failed to allocate padkey\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - memset(padkey, 0, RC4_KEY_LENGTH + 1); - if ((key_len > RC4_KEY_LENGTH) || (key_len < 0)) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: key size too long or key broken\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - memcpy (padkey, key, key_len); - -/* decode hex to binary */ - bin_len = str_len; - bin = xmlMallocAtomic (bin_len); - if (bin == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: Failed to allocate string\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - ret_len = exsltCryptoHex2Bin (str, str_len, bin, bin_len); - -/* decrypt the binary blob */ - ret = xmlMallocAtomic (ret_len + 1); - if (ret == NULL) { - xsltTransformError(tctxt, NULL, tctxt->inst, - "exsltCryptoRc4EncryptFunction: Failed to allocate result\n"); - tctxt->state = XSLT_STATE_STOPPED; - xmlXPathReturnEmptyString (ctxt); - goto done; - } - PLATFORM_RC4_DECRYPT (ctxt, padkey, bin, ret_len, ret, ret_len); - ret[ret_len] = 0; - - xmlXPathReturnString (ctxt, ret); - -done: - if (key != NULL) - xmlFree (key); - if (str != NULL) - xmlFree (str); - if (padkey != NULL) - xmlFree (padkey); - if (bin != NULL) - xmlFree (bin); -} - -/** - * exsltCryptoRegister: - * - * Registers the EXSLT - Crypto module - */ - -void -exsltCryptoRegister (void) { - xsltRegisterExtModuleFunction ((const xmlChar *) "md4", - EXSLT_CRYPTO_NAMESPACE, - exsltCryptoMd4Function); - xsltRegisterExtModuleFunction ((const xmlChar *) "md5", - EXSLT_CRYPTO_NAMESPACE, - exsltCryptoMd5Function); - xsltRegisterExtModuleFunction ((const xmlChar *) "sha1", - EXSLT_CRYPTO_NAMESPACE, - exsltCryptoSha1Function); - xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_encrypt", - EXSLT_CRYPTO_NAMESPACE, - exsltCryptoRc4EncryptFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "rc4_decrypt", - EXSLT_CRYPTO_NAMESPACE, - exsltCryptoRc4DecryptFunction); -} - -#else -/** - * exsltCryptoRegister: - * - * Registers the EXSLT - Crypto module - */ -void -exsltCryptoRegister (void) { -} - -#endif /* defined(HAVE_CRYPTO) */ - -#endif /* EXSLT_CRYPTO_ENABLED */ diff --git a/libxslt/libexslt/date.c b/libxslt/libexslt/date.c deleted file mode 100644 index 3af6f7f..0000000 --- a/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; -} diff --git a/libxslt/libexslt/dynamic.c b/libxslt/libexslt/dynamic.c deleted file mode 100644 index 7b95fc5..0000000 --- a/libxslt/libexslt/dynamic.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * dynamic.c: Implementation of the EXSLT -- Dynamic module - * - * References: - * http://www.exslt.org/dyn/dyn.html - * - * See Copyright for the status of this software. - * - * Authors: - * Mark Vakoc <mark_vakoc@jdedwards.com> - * Thomas Broyer <tbroyer@ltgt.net> - * - * TODO: - * elements: - * functions: - * min - * max - * sum - * map - * closure - */ - -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#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" - -/** - * exsltDynEvaluateFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Evaluates the string as an XPath expression and returns the result - * value, which may be a boolean, number, string, node set, result tree - * fragment or external object. - */ - -static void -exsltDynEvaluateFunction(xmlXPathParserContextPtr ctxt, int nargs) { - xmlChar *str = NULL; - xmlXPathObjectPtr ret = NULL; - - if (ctxt == NULL) - return; - if (nargs != 1) { - xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); - xsltGenericError(xsltGenericErrorContext, - "dyn:evalute() : invalid number of args %d\n", nargs); - ctxt->error = XPATH_INVALID_ARITY; - return; - } - str = xmlXPathPopString(ctxt); - /* return an empty node-set if an empty string is passed in */ - if (!str||!xmlStrlen(str)) { - if (str) xmlFree(str); - valuePush(ctxt,xmlXPathNewNodeSet(NULL)); - return; - } - ret = xmlXPathEval(str,ctxt->context); - if (ret) - valuePush(ctxt,ret); - else { - xsltGenericError(xsltGenericErrorContext, - "dyn:evaluate() : unable to evaluate expression '%s'\n",str); - valuePush(ctxt,xmlXPathNewNodeSet(NULL)); - } - xmlFree(str); - return; -} - -/** - * exsltDynMapFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Evaluates the string as an XPath expression and returns the result - * value, which may be a boolean, number, string, node set, result tree - * fragment or external object. - */ - -static void -exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs) -{ - xmlChar *str = NULL; - xmlNodeSetPtr nodeset = NULL; - xsltTransformContextPtr tctxt; - xmlXPathCompExprPtr comp = NULL; - xmlXPathObjectPtr ret = NULL; - xmlDocPtr oldDoc, container = NULL; - xmlNodePtr oldNode; - int oldContextSize; - int oldProximityPosition; - int i, j; - - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - str = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - nodeset = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) { - if (nodeset != NULL) - xmlXPathFreeNodeSet(nodeset); - if (str != NULL) - xmlFree(str); - valuePush(ctxt, xmlXPathNewNodeSet(NULL)); - return; - } - - ret = xmlXPathNewNodeSet(NULL); - if (ret == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltDynMapFunction: ret == NULL\n"); - goto cleanup; - } - - oldDoc = ctxt->context->doc; - oldNode = ctxt->context->node; - oldContextSize = ctxt->context->contextSize; - oldProximityPosition = ctxt->context->proximityPosition; - - /** - * since we really don't know we're going to be adding node(s) - * down the road we create the RVT regardless - */ - tctxt = xsltXPathGetTransformContext(ctxt); - if (tctxt == NULL) { - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, - "dyn:map : internal error tctxt == NULL\n"); - goto cleanup; - } - container = xsltCreateRVT(tctxt); - if (container == NULL) { - xsltTransformError(tctxt, NULL, NULL, - "dyn:map : internal error container == NULL\n"); - goto cleanup; - } - xsltRegisterLocalRVT(tctxt, container); - if (nodeset && nodeset->nodeNr > 0) { - xmlXPathNodeSetSort(nodeset); - ctxt->context->contextSize = nodeset->nodeNr; - ctxt->context->proximityPosition = 0; - for (i = 0; i < nodeset->nodeNr; i++) { - xmlXPathObjectPtr subResult = NULL; - xmlNodePtr cur = nodeset->nodeTab[i]; - - ctxt->context->proximityPosition++; - ctxt->context->node = cur; - - if (cur->type == XML_NAMESPACE_DECL) { - /* - * The XPath module sets the owner element of a ns-node on - * the ns->next field. - */ - cur = (xmlNodePtr) ((xmlNsPtr) cur)->next; - if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE)) { - xsltGenericError(xsltGenericErrorContext, - "Internal error in exsltDynMapFunction: " - "Cannot retrieve the doc of a namespace node.\n"); - continue; - } - ctxt->context->doc = cur->doc; - } else { - ctxt->context->doc = cur->doc; - } - - subResult = xmlXPathCompiledEval(comp, ctxt->context); - if (subResult != NULL) { - switch (subResult->type) { - case XPATH_NODESET: - if (subResult->nodesetval != NULL) - for (j = 0; j < subResult->nodesetval->nodeNr; - j++) - xmlXPathNodeSetAdd(ret->nodesetval, - subResult->nodesetval-> - nodeTab[j]); - break; - case XPATH_BOOLEAN: - if (container != NULL) { - xmlNodePtr cur = - xmlNewChild((xmlNodePtr) container, NULL, - BAD_CAST "boolean", - BAD_CAST (subResult-> - boolval ? "true" : "")); - if (cur != NULL) { - cur->ns = - xmlNewNs(cur, - BAD_CAST - "http://exslt.org/common", - BAD_CAST "exsl"); - xmlXPathNodeSetAddUnique(ret->nodesetval, - cur); - } - xsltExtensionInstructionResultRegister(tctxt, ret); - } - break; - case XPATH_NUMBER: - if (container != NULL) { - xmlChar *val = - xmlXPathCastNumberToString(subResult-> - floatval); - xmlNodePtr cur = - xmlNewChild((xmlNodePtr) container, NULL, - BAD_CAST "number", val); - if (val != NULL) - xmlFree(val); - - if (cur != NULL) { - cur->ns = - xmlNewNs(cur, - BAD_CAST - "http://exslt.org/common", - BAD_CAST "exsl"); - xmlXPathNodeSetAddUnique(ret->nodesetval, - cur); - } - xsltExtensionInstructionResultRegister(tctxt, ret); - } - break; - case XPATH_STRING: - if (container != NULL) { - xmlNodePtr cur = - xmlNewChild((xmlNodePtr) container, NULL, - BAD_CAST "string", - subResult->stringval); - if (cur != NULL) { - cur->ns = - xmlNewNs(cur, - BAD_CAST - "http://exslt.org/common", - BAD_CAST "exsl"); - xmlXPathNodeSetAddUnique(ret->nodesetval, - cur); - } - xsltExtensionInstructionResultRegister(tctxt, ret); - } - break; - default: - break; - } - xmlXPathFreeObject(subResult); - } - } - } - ctxt->context->doc = oldDoc; - ctxt->context->node = oldNode; - ctxt->context->contextSize = oldContextSize; - ctxt->context->proximityPosition = oldProximityPosition; - - - cleanup: - /* restore the xpath context */ - if (comp != NULL) - xmlXPathFreeCompExpr(comp); - if (nodeset != NULL) - xmlXPathFreeNodeSet(nodeset); - if (str != NULL) - xmlFree(str); - valuePush(ctxt, ret); - return; -} - - -/** - * exsltDynRegister: - * - * Registers the EXSLT - Dynamic module - */ - -void -exsltDynRegister (void) { - xsltRegisterExtModuleFunction ((const xmlChar *) "evaluate", - EXSLT_DYNAMIC_NAMESPACE, - exsltDynEvaluateFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "map", - EXSLT_DYNAMIC_NAMESPACE, - exsltDynMapFunction); - -} diff --git a/libxslt/libexslt/exslt.c b/libxslt/libexslt/exslt.c deleted file mode 100644 index 0bccf17..0000000 --- a/libxslt/libexslt/exslt.c +++ /dev/null @@ -1,40 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#include <libxml/xmlversion.h> - -#include "config.h" - -#include <libxslt/xsltconfig.h> -#include <libxslt/extensions.h> - -#include <libexslt/exsltconfig.h> -#include "exslt.h" - -const char *exsltLibraryVersion = LIBEXSLT_VERSION_STRING - LIBEXSLT_VERSION_EXTRA; -const int exsltLibexsltVersion = LIBEXSLT_VERSION; -const int exsltLibxsltVersion = LIBXSLT_VERSION; -const int exsltLibxmlVersion = LIBXML_VERSION; - -/** - * exsltRegisterAll: - * - * Registers all available EXSLT extensions - */ -void -exsltRegisterAll (void) { - xsltInitGlobals(); - exsltCommonRegister(); -#ifdef EXSLT_CRYPTO_ENABLED - exsltCryptoRegister(); -#endif - exsltMathRegister(); - exsltSetsRegister(); - exsltFuncRegister(); - exsltStrRegister(); - exsltDateRegister(); - exsltSaxonRegister(); - exsltDynRegister(); -} - diff --git a/libxslt/libexslt/exslt.h b/libxslt/libexslt/exslt.h deleted file mode 100644 index 2147308..0000000 --- a/libxslt/libexslt/exslt.h +++ /dev/null @@ -1,102 +0,0 @@ - -#ifndef __EXSLT_H__ -#define __EXSLT_H__ - -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include "exsltexports.h" -#include <libexslt/exsltconfig.h> - -#ifdef __cplusplus -extern "C" { -#endif - -EXSLTPUBVAR const char *exsltLibraryVersion; -EXSLTPUBVAR const int exsltLibexsltVersion; -EXSLTPUBVAR const int exsltLibxsltVersion; -EXSLTPUBVAR const int exsltLibxmlVersion; - -/** - * EXSLT_COMMON_NAMESPACE: - * - * Namespace for EXSLT common functions - */ -#define EXSLT_COMMON_NAMESPACE ((const xmlChar *) "http://exslt.org/common") -/** - * EXSLT_CRYPTO_NAMESPACE: - * - * Namespace for EXSLT crypto functions - */ -#define EXSLT_CRYPTO_NAMESPACE ((const xmlChar *) "http://exslt.org/crypto") -/** - * EXSLT_MATH_NAMESPACE: - * - * Namespace for EXSLT math functions - */ -#define EXSLT_MATH_NAMESPACE ((const xmlChar *) "http://exslt.org/math") -/** - * EXSLT_SETS_NAMESPACE: - * - * Namespace for EXSLT set functions - */ -#define EXSLT_SETS_NAMESPACE ((const xmlChar *) "http://exslt.org/sets") -/** - * EXSLT_FUNCTIONS_NAMESPACE: - * - * Namespace for EXSLT functions extension functions - */ -#define EXSLT_FUNCTIONS_NAMESPACE ((const xmlChar *) "http://exslt.org/functions") -/** - * EXSLT_STRINGS_NAMESPACE: - * - * Namespace for EXSLT strings functions - */ -#define EXSLT_STRINGS_NAMESPACE ((const xmlChar *) "http://exslt.org/strings") -/** - * EXSLT_DATE_NAMESPACE: - * - * Namespace for EXSLT date functions - */ -#define EXSLT_DATE_NAMESPACE ((const xmlChar *) "http://exslt.org/dates-and-times") -/** - * EXSLT_DYNAMIC_NAMESPACE: - * - * Namespace for EXSLT dynamic functions - */ -#define EXSLT_DYNAMIC_NAMESPACE ((const xmlChar *) "http://exslt.org/dynamic") - -/** - * SAXON_NAMESPACE: - * - * Namespace for SAXON extensions functions - */ -#define SAXON_NAMESPACE ((const xmlChar *) "http://icl.com/saxon") - -EXSLTPUBFUN void EXSLTCALL exsltCommonRegister (void); -#ifdef EXSLT_CRYPTO_ENABLED -EXSLTPUBFUN void EXSLTCALL exsltCryptoRegister (void); -#endif -EXSLTPUBFUN void EXSLTCALL exsltMathRegister (void); -EXSLTPUBFUN void EXSLTCALL exsltSetsRegister (void); -EXSLTPUBFUN void EXSLTCALL exsltFuncRegister (void); -EXSLTPUBFUN void EXSLTCALL exsltStrRegister (void); -EXSLTPUBFUN void EXSLTCALL exsltDateRegister (void); -EXSLTPUBFUN void EXSLTCALL exsltSaxonRegister (void); -EXSLTPUBFUN void EXSLTCALL exsltDynRegister(void); - -EXSLTPUBFUN void EXSLTCALL exsltRegisterAll (void); - -EXSLTPUBFUN int EXSLTCALL exsltDateXpathCtxtRegister (xmlXPathContextPtr ctxt, - const xmlChar *prefix); -EXSLTPUBFUN int EXSLTCALL exsltMathXpathCtxtRegister (xmlXPathContextPtr ctxt, - const xmlChar *prefix); -EXSLTPUBFUN int EXSLTCALL exsltSetsXpathCtxtRegister (xmlXPathContextPtr ctxt, - const xmlChar *prefix); -EXSLTPUBFUN int EXSLTCALL exsltStrXpathCtxtRegister (xmlXPathContextPtr ctxt, - const xmlChar *prefix); - -#ifdef __cplusplus -} -#endif -#endif /* __EXSLT_H__ */ - diff --git a/libxslt/libexslt/exsltconfig.h.in b/libxslt/libexslt/exsltconfig.h.in deleted file mode 100644 index b46ffc0..0000000 --- a/libxslt/libexslt/exsltconfig.h.in +++ /dev/null @@ -1,73 +0,0 @@ -/* - * exsltconfig.h: compile-time version informations for the EXSLT library - * - * See Copyright for the status of this software. - * - * daniel@veillard.com - */ - -#ifndef __XML_EXSLTCONFIG_H__ -#define __XML_EXSLTCONFIG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * LIBEXSLT_DOTTED_VERSION: - * - * the version string like "1.2.3" - */ -#define LIBEXSLT_DOTTED_VERSION "@VERSION@" - -/** - * LIBEXSLT_VERSION: - * - * the version number: 1.2.3 value is 10203 - */ -#define LIBEXSLT_VERSION @LIBEXSLT_VERSION_NUMBER@ - -/** - * LIBEXSLT_VERSION_STRING: - * - * the version number string, 1.2.3 value is "10203" - */ -#define LIBEXSLT_VERSION_STRING "@LIBEXSLT_VERSION_NUMBER@" - -/** - * LIBEXSLT_VERSION_EXTRA: - * - * extra version information, used to show a CVS compilation - */ -#define LIBEXSLT_VERSION_EXTRA "@LIBEXSLT_VERSION_EXTRA@" - -/** - * WITH_CRYPTO: - * - * Whether crypto support is configured into exslt - */ -#if @WITH_CRYPTO@ -#define EXSLT_CRYPTO_ENABLED -#endif - -/** - * ATTRIBUTE_UNUSED: - * - * This macro is used to flag unused function parameters to GCC - */ -#ifdef __GNUC__ -#ifdef HAVE_ANSIDECL_H -#include <ansidecl.h> -#endif -#ifndef ATTRIBUTE_UNUSED -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#endif -#else -#define ATTRIBUTE_UNUSED -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __XML_EXSLTCONFIG_H__ */ diff --git a/libxslt/libexslt/exsltexports.h b/libxslt/libexslt/exsltexports.h deleted file mode 100644 index bead915..0000000 --- a/libxslt/libexslt/exsltexports.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * exsltexports.h : macros for marking symbols as exportable/importable. - * - * See Copyright for the status of this software. - * - * igor@zlatkovic.com - */ - -#ifndef __EXSLT_EXPORTS_H__ -#define __EXSLT_EXPORTS_H__ - -/** - * EXSLTPUBFUN, EXSLTPUBVAR, EXSLTCALL - * - * Macros which declare an exportable function, an exportable variable and - * the calling convention used for functions. - * - * Please use an extra block for every platform/compiler combination when - * modifying this, rather than overlong #ifdef lines. This helps - * readability as well as the fact that different compilers on the same - * platform might need different definitions. - */ - -/** - * EXSLTPUBFUN: - * - * Macros which declare an exportable function - */ -#define EXSLTPUBFUN -/** - * EXSLTPUBVAR: - * - * Macros which declare an exportable variable - */ -#define EXSLTPUBVAR extern -/** - * EXSLTCALL: - * - * Macros which declare the called convention for exported functions - */ -#define EXSLTCALL - -/** DOC_DISABLE */ - -/* Windows platform with MS compiler */ -#if defined(_WIN32) && defined(_MSC_VER) - #undef EXSLTPUBFUN - #undef EXSLTPUBVAR - #undef EXSLTCALL - #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) - #define EXSLTPUBFUN __declspec(dllexport) - #define EXSLTPUBVAR __declspec(dllexport) - #else - #define EXSLTPUBFUN - #if !defined(LIBEXSLT_STATIC) - #define EXSLTPUBVAR __declspec(dllimport) extern - #else - #define EXSLTPUBVAR extern - #endif - #endif - #define EXSLTCALL __cdecl - #if !defined _REENTRANT - #define _REENTRANT - #endif -#endif - -/* Windows platform with Borland compiler */ -#if defined(_WIN32) && defined(__BORLANDC__) - #undef EXSLTPUBFUN - #undef EXSLTPUBVAR - #undef EXSLTCALL - #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) - #define EXSLTPUBFUN __declspec(dllexport) - #define EXSLTPUBVAR __declspec(dllexport) extern - #else - #define EXSLTPUBFUN - #if !defined(LIBEXSLT_STATIC) - #define EXSLTPUBVAR __declspec(dllimport) extern - #else - #define EXSLTPUBVAR extern - #endif - #endif - #define EXSLTCALL __cdecl - #if !defined _REENTRANT - #define _REENTRANT - #endif -#endif - -/* Windows platform with GNU compiler (Mingw) */ -#if defined(_WIN32) && defined(__MINGW32__) - #undef EXSLTPUBFUN - #undef EXSLTPUBVAR - #undef EXSLTCALL -/* - #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) -*/ - #if !defined(LIBEXSLT_STATIC) - #define EXSLTPUBFUN __declspec(dllexport) - #define EXSLTPUBVAR __declspec(dllexport) extern - #else - #define EXSLTPUBFUN - #if !defined(LIBEXSLT_STATIC) - #define EXSLTPUBVAR __declspec(dllimport) extern - #else - #define EXSLTPUBVAR extern - #endif - #endif - #define EXSLTCALL __cdecl - #if !defined _REENTRANT - #define _REENTRANT - #endif -#endif - -/* Cygwin platform, GNU compiler */ -#if defined(_WIN32) && defined(__CYGWIN__) - #undef EXSLTPUBFUN - #undef EXSLTPUBVAR - #undef EXSLTCALL - #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) - #define EXSLTPUBFUN __declspec(dllexport) - #define EXSLTPUBVAR __declspec(dllexport) - #else - #define EXSLTPUBFUN - #if !defined(LIBEXSLT_STATIC) - #define EXSLTPUBVAR __declspec(dllimport) extern - #else - #define EXSLTPUBVAR - #endif - #endif - #define EXSLTCALL __cdecl -#endif - -/* Compatibility */ -#if !defined(LIBEXSLT_PUBLIC) -#define LIBEXSLT_PUBLIC EXSLTPUBVAR -#endif - -#endif /* __EXSLT_EXPORTS_H__ */ - - diff --git a/libxslt/libexslt/functions.c b/libxslt/libexslt/functions.c deleted file mode 100644 index 0795a13..0000000 --- a/libxslt/libexslt/functions.c +++ /dev/null @@ -1,795 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#endif - -#include <string.h> - -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> -#include <libxml/hash.h> -#include <libxml/debugXML.h> - -#include <libxslt/xsltutils.h> -#include <libxslt/variables.h> -#include <libxslt/xsltInternals.h> -#include <libxslt/extensions.h> -#include <libxslt/transform.h> -#include <libxslt/imports.h> - -#include "exslt.h" - -typedef struct _exsltFuncFunctionData exsltFuncFunctionData; -struct _exsltFuncFunctionData { - int nargs; /* number of arguments to the function */ - xmlNodePtr content; /* the func:fuction template content */ -}; - -typedef struct _exsltFuncData exsltFuncData; -struct _exsltFuncData { - xmlHashTablePtr funcs; /* pointer to the stylesheet module data */ - xmlXPathObjectPtr result; /* returned by func:result */ - int error; /* did an error occur? */ - xmlDocPtr RVT; /* result tree fragment */ -}; - -typedef struct _exsltFuncResultPreComp exsltFuncResultPreComp; -struct _exsltFuncResultPreComp { - xsltElemPreComp comp; - xmlXPathCompExprPtr select; - xmlNsPtr *nsList; - int nsNr; -}; - -/* Used for callback function in exsltInitFunc */ -typedef struct _exsltFuncImportRegData exsltFuncImportRegData; -struct _exsltFuncImportRegData { - xsltTransformContextPtr ctxt; - xmlHashTablePtr hash; -}; - -static void exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, - int nargs); -static exsltFuncFunctionData *exsltFuncNewFunctionData(void); - -#define MAX_FUNC_RECURSION 1000 - -/*static const xmlChar *exsltResultDataID = (const xmlChar *) "EXSLT Result";*/ - -/** - * exsltFuncRegisterFunc: - * @func: the #exsltFuncFunctionData for the function - * @ctxt: an XSLT transformation context - * @URI: the function namespace URI - * @name: the function name - * - * Registers a function declared by a func:function element - */ -static void -exsltFuncRegisterFunc (exsltFuncFunctionData *data, - xsltTransformContextPtr ctxt, - const xmlChar *URI, const xmlChar *name, - ATTRIBUTE_UNUSED const xmlChar *ignored) { - if ((data == NULL) || (ctxt == NULL) || (URI == NULL) || (name == NULL)) - return; - - xsltGenericDebug(xsltGenericDebugContext, - "exsltFuncRegisterFunc: register {%s}%s\n", - URI, name); - xsltRegisterExtFunction(ctxt, name, URI, - exsltFuncFunctionFunction); -} - -/* - * exsltFuncRegisterImportFunc - * @data: the exsltFuncFunctionData for the function - * @ch: structure containing context and hash table - * @URI: the function namespace URI - * @name: the function name - * - * Checks if imported function is already registered in top-level - * stylesheet. If not, copies function data and registers function - */ -static void -exsltFuncRegisterImportFunc (exsltFuncFunctionData *data, - exsltFuncImportRegData *ch, - const xmlChar *URI, const xmlChar *name, - ATTRIBUTE_UNUSED const xmlChar *ignored) { - exsltFuncFunctionData *func=NULL; - - if ((data == NULL) || (ch == NULL) || (URI == NULL) || (name == NULL)) - return; - - if (ch->ctxt == NULL || ch->hash == NULL) - return; - - /* Check if already present */ - func = (exsltFuncFunctionData*)xmlHashLookup2(ch->hash, URI, name); - if (func == NULL) { /* Not yet present - copy it in */ - func = exsltFuncNewFunctionData(); - if (func == NULL) - return; - memcpy(func, data, sizeof(exsltFuncFunctionData)); - if (xmlHashAddEntry2(ch->hash, URI, name, func) < 0) { - xsltGenericError(xsltGenericErrorContext, - "Failed to register function {%s}%s\n", - URI, name); - } else { /* Do the registration */ - xsltGenericDebug(xsltGenericDebugContext, - "exsltFuncRegisterImportFunc: register {%s}%s\n", - URI, name); - xsltRegisterExtFunction(ch->ctxt, name, URI, - exsltFuncFunctionFunction); - } - } -} - -/** - * exsltFuncInit: - * @ctxt: an XSLT transformation context - * @URI: the namespace URI for the extension - * - * Initializes the EXSLT - Functions module. - * Called at transformation-time; merges all - * functions declared in the import tree taking - * import precedence into account, i.e. overriding - * functions with lower import precedence. - * - * Returns the data for this transformation - */ -static exsltFuncData * -exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) { - exsltFuncData *ret; - xsltStylesheetPtr tmp; - exsltFuncImportRegData ch; - xmlHashTablePtr hash; - - ret = (exsltFuncData *) xmlMalloc (sizeof(exsltFuncData)); - if (ret == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncInit: not enough memory\n"); - return(NULL); - } - memset(ret, 0, sizeof(exsltFuncData)); - - ret->result = NULL; - ret->error = 0; - - ch.hash = (xmlHashTablePtr) xsltStyleGetExtData(ctxt->style, URI); - ret->funcs = ch.hash; - xmlHashScanFull(ch.hash, (xmlHashScannerFull) exsltFuncRegisterFunc, ctxt); - tmp = ctxt->style; - ch.ctxt = ctxt; - while ((tmp=xsltNextImport(tmp))!=NULL) { - hash = xsltGetExtInfo(tmp, URI); - if (hash != NULL) { - xmlHashScanFull(hash, - (xmlHashScannerFull) exsltFuncRegisterImportFunc, &ch); - } - } - - return(ret); -} - -/** - * exsltFuncShutdown: - * @ctxt: an XSLT transformation context - * @URI: the namespace URI for the extension - * @data: the module data to free up - * - * Shutdown the EXSLT - Functions module - * Called at transformation-time. - */ -static void -exsltFuncShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, - const xmlChar *URI ATTRIBUTE_UNUSED, - exsltFuncData *data) { - if (data->result != NULL) - xmlXPathFreeObject(data->result); - xmlFree(data); -} - -/** - * exsltFuncStyleInit: - * @style: an XSLT stylesheet - * @URI: the namespace URI for the extension - * - * Allocates the stylesheet data for EXSLT - Function - * Called at compile-time. - * - * Returns the allocated data - */ -static xmlHashTablePtr -exsltFuncStyleInit (xsltStylesheetPtr style ATTRIBUTE_UNUSED, - const xmlChar *URI ATTRIBUTE_UNUSED) { - return xmlHashCreate(1); -} - -/** - * exsltFuncStyleShutdown: - * @style: an XSLT stylesheet - * @URI: the namespace URI for the extension - * @data: the stylesheet data to free up - * - * Shutdown the EXSLT - Function module - * Called at compile-time. - */ -static void -exsltFuncStyleShutdown (xsltStylesheetPtr style ATTRIBUTE_UNUSED, - const xmlChar *URI ATTRIBUTE_UNUSED, - xmlHashTablePtr data) { - xmlHashFree(data, (xmlHashDeallocator) xmlFree); -} - -/** - * exsltFuncNewFunctionData: - * - * Allocates an #exslFuncFunctionData object - * - * Returns the new structure - */ -static exsltFuncFunctionData * -exsltFuncNewFunctionData (void) { - exsltFuncFunctionData *ret; - - ret = (exsltFuncFunctionData *) xmlMalloc (sizeof(exsltFuncFunctionData)); - if (ret == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncNewFunctionData: not enough memory\n"); - return (NULL); - } - memset(ret, 0, sizeof(exsltFuncFunctionData)); - - ret->nargs = 0; - ret->content = NULL; - - return(ret); -} - -/** - * exsltFreeFuncResultPreComp: - * @comp: the #exsltFuncResultPreComp to free up - * - * Deallocates an #exsltFuncResultPreComp - */ -static void -exsltFreeFuncResultPreComp (exsltFuncResultPreComp *comp) { - if (comp == NULL) - return; - - if (comp->select != NULL) - xmlXPathFreeCompExpr (comp->select); - if (comp->nsList != NULL) - xmlFree(comp->nsList); - xmlFree(comp); -} - -/** - * exsltFuncFunctionFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Evaluates the func:function element that defines the called function. - */ -static void -exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr oldResult, ret; - exsltFuncData *data; - exsltFuncFunctionData *func; - xmlNodePtr paramNode, oldInsert, fake; - int oldBase; - xsltStackElemPtr params = NULL, param; - xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); - int i, notSet; - struct objChain { - struct objChain *next; - xmlXPathObjectPtr obj; - }; - struct objChain *savedObjChain = NULL, *savedObj; - - /* - * retrieve func:function template - */ - data = (exsltFuncData *) xsltGetExtData (tctxt, - EXSLT_FUNCTIONS_NAMESPACE); - oldResult = data->result; - data->result = NULL; - - func = (exsltFuncFunctionData*) xmlHashLookup2 (data->funcs, - ctxt->context->functionURI, - ctxt->context->function); - if (func == NULL) { - /* Should never happen */ - xsltGenericError(xsltGenericErrorContext, - "{%s}%s: not found\n", - ctxt->context->functionURI, ctxt->context->function); - ctxt->error = XPATH_UNKNOWN_FUNC_ERROR; - return; - } - - /* - * params handling - */ - if (nargs > func->nargs) { - xsltGenericError(xsltGenericErrorContext, - "{%s}%s: called with too many arguments\n", - ctxt->context->functionURI, ctxt->context->function); - ctxt->error = XPATH_INVALID_ARITY; - return; - } - if (func->content != NULL) { - paramNode = func->content->prev; - } - else - paramNode = NULL; - if ((paramNode == NULL) && (func->nargs != 0)) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncFunctionFunction: nargs != 0 and " - "param == NULL\n"); - return; - } - if (tctxt->funcLevel > MAX_FUNC_RECURSION) { - xsltGenericError(xsltGenericErrorContext, - "{%s}%s: detected a recursion\n", - ctxt->context->functionURI, ctxt->context->function); - ctxt->error = XPATH_MEMORY_ERROR; - return; - } - tctxt->funcLevel++; - - /* - * We have a problem with the evaluation of function parameters. - * The original library code did not evaluate XPath expressions until - * the last moment. After version 1.1.17 of the libxslt, the logic - * of other parts of the library was changed, and the evaluation of - * XPath expressions within parameters now takes place as soon as the - * parameter is parsed/evaluated (xsltParseStylesheetCallerParam). - * This means that the parameters need to be evaluated in lexical - * order (since a variable is "in scope" as soon as it is declared). - * However, on entry to this routine, the values (from the caller) are - * in reverse order (held on the XPath context variable stack). To - * accomplish what is required, I have added code to pop the XPath - * objects off of the stack at the beginning and save them, then use - * them (in the reverse order) as the params are evaluated. This - * requires an xmlMalloc/xmlFree for each param set by the caller, - * which is not very nice. There is probably a much better solution - * (like change other code to delay the evaluation). - */ - /* - * In order to give the function params and variables a new 'scope' - * we change varsBase in the context. - */ - oldBase = tctxt->varsBase; - tctxt->varsBase = tctxt->varsNr; - /* If there are any parameters */ - if (paramNode != NULL) { - /* Fetch the stored argument values from the caller */ - for (i = 0; i < nargs; i++) { - savedObj = xmlMalloc(sizeof(struct objChain)); - savedObj->next = savedObjChain; - savedObj->obj = valuePop(ctxt); - savedObjChain = savedObj; - } - - /* - * Prepare to process params in reverse order. First, go to - * the beginning of the param chain. - */ - for (i = 1; i <= func->nargs; i++) { - if (paramNode->prev == NULL) - break; - paramNode = paramNode->prev; - } - /* - * i has total # params found, nargs is number which are present - * as arguments from the caller - * Calculate the number of un-set parameters - */ - notSet = func->nargs - nargs; - for (; i > 0; i--) { - param = xsltParseStylesheetCallerParam (tctxt, paramNode); - if (i > notSet) { /* if parameter value set */ - param->computed = 1; - if (param->value != NULL) - xmlXPathFreeObject(param->value); - savedObj = savedObjChain; /* get next val from chain */ - param->value = savedObj->obj; - savedObjChain = savedObjChain->next; - xmlFree(savedObj); - } - xsltLocalVariablePush(tctxt, param, -1); - param->next = params; - params = param; - paramNode = paramNode->next; - } - } - /* - * actual processing - */ - fake = xmlNewDocNode(tctxt->output, NULL, - (const xmlChar *)"fake", NULL); - oldInsert = tctxt->insert; - tctxt->insert = fake; - xsltApplyOneTemplate (tctxt, xmlXPathGetContextNode(ctxt), - func->content, NULL, NULL); - xsltLocalVariablePop(tctxt, tctxt->varsBase, -2); - tctxt->insert = oldInsert; - tctxt->varsBase = oldBase; /* restore original scope */ - if (params != NULL) - xsltFreeStackElemList(params); - - if (data->error != 0) - goto error; - - if (data->result != NULL) { - ret = data->result; - } else - ret = xmlXPathNewCString(""); - - data->result = oldResult; - - /* - * It is an error if the instantiation of the template results in - * the generation of result nodes. - */ - if (fake->children != NULL) { -#ifdef LIBXML_DEBUG_ENABLED - xmlDebugDumpNode (stderr, fake, 1); -#endif - xsltGenericError(xsltGenericErrorContext, - "{%s}%s: cannot write to result tree while " - "executing a function\n", - ctxt->context->functionURI, ctxt->context->function); - xmlFreeNode(fake); - goto error; - } - xmlFreeNode(fake); - valuePush(ctxt, ret); - -error: - /* - * IMPORTANT: This enables previously tree fragments marked as - * being results of a function, to be garbage-collected after - * the calling process exits. - */ - xsltExtensionInstructionResultFinalize(tctxt); - tctxt->funcLevel--; -} - - -static void -exsltFuncFunctionComp (xsltStylesheetPtr style, xmlNodePtr inst) { - xmlChar *name, *prefix; - xmlNsPtr ns; - xmlHashTablePtr data; - exsltFuncFunctionData *func; - - if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE)) - return; - - { - xmlChar *qname; - - qname = xmlGetProp(inst, (const xmlChar *) "name"); - name = xmlSplitQName2 (qname, &prefix); - xmlFree(qname); - } - if ((name == NULL) || (prefix == NULL)) { - xsltGenericError(xsltGenericErrorContext, - "func:function: not a QName\n"); - if (name != NULL) - xmlFree(name); - return; - } - /* namespace lookup */ - ns = xmlSearchNs (inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "func:function: undeclared prefix %s\n", - prefix); - xmlFree(name); - xmlFree(prefix); - return; - } - xmlFree(prefix); - - xsltParseTemplateContent(style, inst); - - /* - * Create function data - */ - func = exsltFuncNewFunctionData(); - if (func == NULL) { - xmlFree(name); - return; - } - func->content = inst->children; - while (IS_XSLT_ELEM(func->content) && - IS_XSLT_NAME(func->content, "param")) { - func->content = func->content->next; - func->nargs++; - } - - /* - * Register the function data such that it can be retrieved - * by exslFuncFunctionFunction - */ -#ifdef XSLT_REFACTORED - /* - * Ensure that the hash table will be stored in the *current* - * stylesheet level in order to correctly evaluate the - * import precedence. - */ - data = (xmlHashTablePtr) - xsltStyleStylesheetLevelGetExtData(style, - EXSLT_FUNCTIONS_NAMESPACE); -#else - data = (xmlHashTablePtr) - xsltStyleGetExtData (style, EXSLT_FUNCTIONS_NAMESPACE); -#endif - if (data == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncFunctionComp: no stylesheet data\n"); - xmlFree(name); - return; - } - - if (xmlHashAddEntry2 (data, ns->href, name, func) < 0) { - xsltTransformError(NULL, style, inst, - "Failed to register function {%s}%s\n", - ns->href, name); - style->errors++; - } else { - xsltGenericDebug(xsltGenericDebugContext, - "exsltFuncFunctionComp: register {%s}%s\n", - ns->href, name); - } - xmlFree(name); -} - -static xsltElemPreCompPtr -exsltFuncResultComp (xsltStylesheetPtr style, xmlNodePtr inst, - xsltTransformFunction function) { - xmlNodePtr test; - xmlChar *sel; - exsltFuncResultPreComp *ret; - - if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE)) - return (NULL); - - /* - * "Validity" checking - */ - /* it is an error to have any following sibling elements aside - * from the xsl:fallback element. - */ - for (test = inst->next; test != NULL; test = test->next) { - if (test->type != XML_ELEMENT_NODE) - continue; - if (IS_XSLT_ELEM(test) && IS_XSLT_NAME(test, "fallback")) - continue; - xsltGenericError(xsltGenericErrorContext, - "exsltFuncResultElem: only xsl:fallback is " - "allowed to follow func:result\n"); - style->errors++; - return (NULL); - } - /* it is an error for a func:result element to not be a descendant - * of func:function. - * it is an error if a func:result occurs within a func:result - * element. - * it is an error if instanciating the content of a variable - * binding element (i.e. xsl:variable, xsl:param) results in the - * instanciation of a func:result element. - */ - for (test = inst->parent; test != NULL; test = test->parent) { - if (IS_XSLT_ELEM(test) && - IS_XSLT_NAME(test, "stylesheet")) { - xsltGenericError(xsltGenericErrorContext, - "func:result element not a descendant " - "of a func:function\n"); - style->errors++; - return (NULL); - } - if ((test->ns != NULL) && - (xmlStrEqual(test->ns->href, EXSLT_FUNCTIONS_NAMESPACE))) { - if (xmlStrEqual(test->name, (const xmlChar *) "function")) { - break; - } - if (xmlStrEqual(test->name, (const xmlChar *) "result")) { - xsltGenericError(xsltGenericErrorContext, - "func:result element not allowed within" - " another func:result element\n"); - style->errors++; - return (NULL); - } - } - if (IS_XSLT_ELEM(test) && - (IS_XSLT_NAME(test, "variable") || - IS_XSLT_NAME(test, "param"))) { - xsltGenericError(xsltGenericErrorContext, - "func:result element not allowed within" - " a variable binding element\n"); - style->errors++; - return (NULL); - } - } - - /* - * Precomputation - */ - ret = (exsltFuncResultPreComp *) - xmlMalloc (sizeof(exsltFuncResultPreComp)); - if (ret == NULL) { - xsltPrintErrorContext(NULL, NULL, NULL); - xsltGenericError(xsltGenericErrorContext, - "exsltFuncResultComp : malloc failed\n"); - style->errors++; - return (NULL); - } - memset(ret, 0, sizeof(exsltFuncResultPreComp)); - - xsltInitElemPreComp ((xsltElemPreCompPtr) ret, style, inst, function, - (xsltElemPreCompDeallocator) exsltFreeFuncResultPreComp); - ret->select = NULL; - - /* - * Precompute the select attribute - */ - sel = xmlGetNsProp(inst, (const xmlChar *) "select", NULL); - if (sel != NULL) { - ret->select = xmlXPathCompile (sel); - xmlFree(sel); - } - /* - * Precompute the namespace list - */ - ret->nsList = xmlGetNsList(inst->doc, inst); - if (ret->nsList != NULL) { - int i = 0; - while (ret->nsList[i] != NULL) - i++; - ret->nsNr = i; - } - return ((xsltElemPreCompPtr) ret); -} - -static void -exsltFuncResultElem (xsltTransformContextPtr ctxt, - xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, - exsltFuncResultPreComp *comp) { - exsltFuncData *data; - xmlXPathObjectPtr ret; - - - /* It is an error if instantiating the content of the - * func:function element results in the instantiation of more than - * one func:result elements. - */ - data = (exsltFuncData *) xsltGetExtData (ctxt, EXSLT_FUNCTIONS_NAMESPACE); - if (data == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncReturnElem: data == NULL\n"); - return; - } - if (data->result != NULL) { - xsltGenericError(xsltGenericErrorContext, - "func:result already instanciated\n"); - data->error = 1; - return; - } - /* - * Processing - */ - if (comp->select != NULL) { - xmlNsPtr *oldXPNsList; - int oldXPNsNr; - xmlNodePtr oldXPContextNode; - /* If the func:result element has a select attribute, then the - * value of the attribute must be an expression and the - * returned value is the object that results from evaluating - * the expression. In this case, the content must be empty. - */ - if (inst->children != NULL) { - xsltGenericError(xsltGenericErrorContext, - "func:result content must be empty if" - " the function has a select attribute\n"); - data->error = 1; - return; - } - oldXPNsList = ctxt->xpathCtxt->namespaces; - oldXPNsNr = ctxt->xpathCtxt->nsNr; - oldXPContextNode = ctxt->xpathCtxt->node; - - ctxt->xpathCtxt->namespaces = comp->nsList; - ctxt->xpathCtxt->nsNr = comp->nsNr; - - ret = xmlXPathCompiledEval(comp->select, ctxt->xpathCtxt); - - ctxt->xpathCtxt->node = oldXPContextNode; - ctxt->xpathCtxt->nsNr = oldXPNsNr; - ctxt->xpathCtxt->namespaces = oldXPNsList; - - if (ret == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncResultElem: ret == NULL\n"); - return; - } - /* - * Mark it as a function result in order to avoid garbage - * collecting of tree fragments before the function exits. - */ - xsltExtensionInstructionResultRegister(ctxt, ret); - } else if (inst->children != NULL) { - /* If the func:result element does not have a select attribute - * and has non-empty content (i.e. the func:result element has - * one or more child nodes), then the content of the - * func:result element specifies the value. - */ - xmlNodePtr oldInsert; - xmlDocPtr container; - - container = xsltCreateRVT(ctxt); - if (container == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncResultElem: out of memory\n"); - data->error = 1; - return; - } - xsltRegisterLocalRVT(ctxt, container); - - oldInsert = ctxt->insert; - ctxt->insert = (xmlNodePtr) container; - xsltApplyOneTemplate (ctxt, ctxt->xpathCtxt->node, - inst->children, NULL, NULL); - ctxt->insert = oldInsert; - - ret = xmlXPathNewValueTree((xmlNodePtr) container); - if (ret == NULL) { - xsltGenericError(xsltGenericErrorContext, - "exsltFuncResultElem: ret == NULL\n"); - data->error = 1; - } else { - ret->boolval = 0; /* Freeing is not handled there anymore */ - /* - * Mark it as a function result in order to avoid garbage - * collecting of tree fragments before the function exits. - */ - xsltExtensionInstructionResultRegister(ctxt, ret); - } - } else { - /* If the func:result element has empty content and does not - * have a select attribute, then the returned value is an - * empty string. - */ - ret = xmlXPathNewCString(""); - } - data->result = ret; -} - -/** - * exsltFuncRegister: - * - * Registers the EXSLT - Functions module - */ -void -exsltFuncRegister (void) { - xsltRegisterExtModuleFull (EXSLT_FUNCTIONS_NAMESPACE, - (xsltExtInitFunction) exsltFuncInit, - (xsltExtShutdownFunction) exsltFuncShutdown, - (xsltStyleExtInitFunction) exsltFuncStyleInit, - (xsltStyleExtShutdownFunction) exsltFuncStyleShutdown); - - xsltRegisterExtModuleTopLevel ((const xmlChar *) "function", - EXSLT_FUNCTIONS_NAMESPACE, - exsltFuncFunctionComp); - xsltRegisterExtModuleElement ((const xmlChar *) "result", - EXSLT_FUNCTIONS_NAMESPACE, - (xsltPreComputeFunction)exsltFuncResultComp, - (xsltTransformFunction) exsltFuncResultElem); -} diff --git a/libxslt/libexslt/libexslt.3 b/libxslt/libexslt/libexslt.3 deleted file mode 100644 index 83c57d3..0000000 --- a/libxslt/libexslt/libexslt.3 +++ /dev/null @@ -1,270 +0,0 @@ -.TH LIBEXSLT 3 "04 November 2003" libxslt -.SH NAME -libexslt \- extension library for XSLT -.SH SYNOPSIS -.B #include <libexslt/exslt.h> -.sp -.B void exsltCommonRegister(void); -.br -.B void exsltDateRegister(void); -.br -.B void exsltDynRegister(void); -.br -.B void exsltFuncRegister(void); -.br -.B void exsltMathRegister(void); -.br -.B void exsltSetsRegister(void); -.br -.B void exsltStrRegister(void); -.br -.B void exsltRegisterAll(void); -.br -.B void exsltSaxonRegister(void); -.SH DESCRIPTION -The -.B libexslt -library is used to provide extensions to -.SM XSLT -functions. These extensions come from the -.SM EXSLT -project <http://www.exslt.org/> -.LP -.SH USAGE -To make use of these functions in -.SM XSLT -the appropriate namespace must be defined on the -.B xsl:stylesheet -element. To enable support for them in -.BR libxslt (3) -you must call the appropriate functions (listed in the -.B SYNOPSIS -section) to register the extensions. The -.I xslt-config -shell script can be used to obtain the necessary flags for -the pre-processor and linker. -The supported extensions are: -.SS COMMON -.TP 2.2i -Namespace: http://exslt.org/common -.TP 2.2i -See http://www.exslt.org/exsl/index.html for a description. -.TP 2.2i -.B node-set() -convert the given RTF into a node-set. -.TP -.B object-type() -returns the type of the given argument. -.TP -.B document -Create multiple output documents. See http://www.exslt.org/exsl/elements/document/index.html - -.SS MATH -.TP 2.2i -Namespace: http://exslt.org/math -.TP 2.2i -See http://www.exslt.org/math/index.html for a description. -.TP 2.2i -.B min() -returns the minimum value of the given node-set -.TP -.B max() -returns the maximum value of the given node-set -.TP -.B highest() -returns the nodes in the node-set whose value is the maximum value for the node-set. -.TP -.B lowest() -returns the nodes in the node-set whose value is the minimum value for the node-set. -.TP -.B constant() -returns a number value of the given constant with the given precision. The constants are PI, E, SQRRT2, LN2, LN10, LOG2E, and SQRT1_2. -.TP -.B random() -returns a random number between 0 and 1 inclusive. -.TP -.B abs() -returns the absolute value of the argument. -.TP -.B sqrt() -returns the square root of the argument. -.TP -.B power() -returns the power base and power arguments. -.TP -.B log() -returns the natural log of the argument. -.TP -.B sin() -returns the sine of the argument. -.TP -.B cos() -returns the cosine of the argument. -.TP -.B tan() -returns the tangent of the argument. -.TP -.B asin() -returns the arc sine of the argument. -.TP -.B acos() -returns the arc cosine of the argument. -.TP -.B atan() -returns the arc tangent of the argument. -.TP -.B atan2() -returns the arc tangent function of the y/x arguments. -.TP -.B exp() -returns the exponential function of the argument. - -.SS SETS -.TP 2.2i -Namespace: http://exslt.org/sets -.TP 2.2i -See http://www.exslt.org/set/index.html for a description. -.TP 2.2i -.B difference() -returns the difference between the two given node-sets. -.TP -.B intersection() -returns a node-set of the nodes within both given node-sets. -.TP -.B distinct() -returns a node-set of all nodes in the first argument that are not in the seconds argument. -.TP -.B has-same-node() -returns TRUE if there is an intersection between the two given node-sets. -.TP -.B leading() -returns a node-set of all nodes in the first argument that precede the first node in the second argument. -.TP -.B trailing() -returns a node-set of all nodes in the first argument that follow the first node in the second argument. - -.SS "DATES and TIMES" -.TP 2.2i -Namespace: http://exslt.org/dates-and-times -.TP 2.2i -See http://www.exslt.org/date/date.html for a description. -.TP 2.2i -.B date-time() -returns the current date and time as a date/time string. -.TP -.B date() -returns the date specified in the given date/time string. -.TP -.B time() -returns the time specified in the date/time string given as the argument. -.TP -.B year() -returns the year of a date as a number. -.TP -.B leap-year() -returns true if the year given in a date is a leap year. -.TP -.B month-in-year() -returns the month of a date as a number. -.TP -.B month-name() -returns the full name of the month of a date. -.TP -.B month-abbreviation() -returns the abbreviation of the month of a date. -.TP -.B week-in-year() -returns the week of the year as a number. -.TP -.B week-in-month() -returns the week in a month of a date as a number. -.TP -.B day-in-year() -returns the month of a date as a number. -.TP -.B day-in-month() -returns the day of a date as a number. -.TP -.B day-of-week-in-month() -returns the day-of-the-week in a month of a date as a number. -.TP -.B day-in-week() -returns the day of the week given in a date as a number. -.TP -.B day-name() -returns the full name of the day of the week of a date. -.TP -.B day-abbreviation() -returns the abbreviation of the day of the week of a date. -.TP -.B hour-in-day() -returns the hour of the day as a number. -.TP -.B minute-in-hour() -returns the minute of the hour as a number. -.TP -.B second-in-minute() -returns the second of the minute as a number. -.TP -.B seconds() -returns the number of seconds specified by the argument string. -.TP -.B add() -returns the date/time resulting from adding a duration to a date/time. -.TP -.B add-duration() -returns the duration resulting from adding two given durations together. -.TP -.B difference() -returns the duration between the first date and the second date. -.TP -.B duration() -returns a duration string that represents the given number of seconds since 1970-01-01T00:00:00. - -.SS STRINGS -.TP 2.2i -Namespace: http://exslt.org/strings -.TP 2.2i -See http://www.exslt.org/str/index.html for a description. -.TP 2.2i -.B tokenize() -returns a node set of token elements, each containing one token from the string. -.TP -.B padding() -returns a string padded to a certain length. -.TP -.B align() -returns a string aligned within another string. -.TP -.B concat() -returns the concatenation of the string values of the nodes in that node set. - -.SS FUNCTIONS -.TP 2.2i -Namespace: http://exslt.org/functions -.TP 2.2i -See http://www.exslt.org/func/index.html for a description. -.TP 2.2i -.B function -declares an extension function. -.TP -.B result -returns the result of an extension function declared in function(). -.SH FILES -.TP -.I /usr/bin/xslt-config -shell script giving pre-processor and linker flags. -.TP -.I /usr/lib/libexslt.a -static library -.TP -.I /usr/lib/libexslt.so -sharable library -.SH AUTHORS -Manual page by Heiko W. Rupp (hwr@pilhuhn.de) -.SH "SEE ALSO" -.BR libxml (3), -.BR libxslt (3), -.BR xmllint (1) -.BR xsltproc (1), -.\" end of manual page diff --git a/libxslt/libexslt/libexslt.h b/libxslt/libexslt/libexslt.h deleted file mode 100644 index 2dd9b37..0000000 --- a/libxslt/libexslt/libexslt.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * libexslt.h: internal header only used during the compilation of libexslt - * - * See COPYRIGHT for the status of this software - * - * Author: daniel@veillard.com - */ - -#ifndef __XSLT_LIBEXSLT_H__ -#define __XSLT_LIBEXSLT_H__ - -#if defined(WIN32) && !defined (__CYGWIN__) && !defined (__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#endif - -#include <libxslt/xsltconfig.h> -#include <libxml/xmlversion.h> - -#if !defined LIBEXSLT_PUBLIC -#if (defined (__CYGWIN__) || defined _MSC_VER) && !defined IN_LIBEXSLT && !defined LIBEXSLT_STATIC -#define LIBEXSLT_PUBLIC __declspec(dllimport) -#else -#define LIBEXSLT_PUBLIC -#endif -#endif - -#endif /* ! __XSLT_LIBEXSLT_H__ */ diff --git a/libxslt/libexslt/math.c b/libxslt/libexslt/math.c deleted file mode 100644 index 6b24dbe..0000000 --- a/libxslt/libexslt/math.c +++ /dev/null @@ -1,1202 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#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> - -#ifdef HAVE_MATH_H -#include <math.h> -#endif - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#include "exslt.h" - -/** - * exsltMathMin: - * @ns: a node-set - * - * Implements the EXSLT - Math min() function: - * number math:min (node-set) - * - * Returns the minimum value of the nodes passed as the argument, or - * xmlXPathNAN if @ns is NULL or empty or if one of the nodes - * turns into NaN. - */ -static double -exsltMathMin (xmlNodeSetPtr ns) { - double ret, cur; - int i; - - if ((ns == NULL) || (ns->nodeNr == 0)) - return(xmlXPathNAN); - ret = xmlXPathCastNodeToNumber(ns->nodeTab[0]); - if (xmlXPathIsNaN(ret)) - return(xmlXPathNAN); - for (i = 1; i < ns->nodeNr; i++) { - cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]); - if (xmlXPathIsNaN(cur)) - return(xmlXPathNAN); - if (cur < ret) - ret = cur; - } - return(ret); -} - -/** - * exsltMathMinFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathMin for use by the XPath processor. - */ -static void -exsltMathMinFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr ns; - double ret; - void *user = NULL; - - if (nargs != 1) { - xsltGenericError(xsltGenericErrorContext, - "math:min: invalid number of arguments\n"); - ctxt->error = XPATH_INVALID_ARITY; - 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; - - ret = exsltMathMin(ns); - - xmlXPathFreeNodeSet(ns); - if (user != NULL) - xmlFreeNodeList((xmlNodePtr)user); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathMax: - * @ns: a node-set - * - * Implements the EXSLT - Math max() function: - * number math:max (node-set) - * - * Returns the maximum value of the nodes passed as arguments, or - * xmlXPathNAN if @ns is NULL or empty or if one of the nodes - * turns into NaN. - */ -static double -exsltMathMax (xmlNodeSetPtr ns) { - double ret, cur; - int i; - - if ((ns == NULL) || (ns->nodeNr == 0)) - return(xmlXPathNAN); - ret = xmlXPathCastNodeToNumber(ns->nodeTab[0]); - if (xmlXPathIsNaN(ret)) - return(xmlXPathNAN); - for (i = 1; i < ns->nodeNr; i++) { - cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]); - if (xmlXPathIsNaN(cur)) - return(xmlXPathNAN); - if (cur > ret) - ret = cur; - } - return(ret); -} - -/** - * exsltMathMaxFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathMax for use by the XPath processor. - */ -static void -exsltMathMaxFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr ns; - double ret; - void *user = NULL; - - 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 = 0; - } - ns = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathMax(ns); - - xmlXPathFreeNodeSet(ns); - - if (user != NULL) - xmlFreeNodeList((xmlNodePtr)user); - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathHighest: - * @ns: a node-set - * - * Implements the EXSLT - Math highest() function: - * node-set math:highest (node-set) - * - * Returns the nodes in the node-set whose value is the maximum value - * for the node-set. - */ -static xmlNodeSetPtr -exsltMathHighest (xmlNodeSetPtr ns) { - xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL); - double max, cur; - int i; - - if ((ns == NULL) || (ns->nodeNr == 0)) - return(ret); - - max = xmlXPathCastNodeToNumber(ns->nodeTab[0]); - if (xmlXPathIsNaN(max)) - return(ret); - else - xmlXPathNodeSetAddUnique(ret, ns->nodeTab[0]); - - for (i = 1; i < ns->nodeNr; i++) { - cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]); - if (xmlXPathIsNaN(cur)) { - xmlXPathEmptyNodeSet(ret); - return(ret); - } - if (cur < max) - continue; - if (cur > max) { - max = cur; - xmlXPathEmptyNodeSet(ret); - xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]); - continue; - } - xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]); - } - return(ret); -} - -/** - * exsltMathHighestFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathHighest for use by the XPath processor - */ -static void -exsltMathHighestFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr ns, ret; - void *user = NULL; - - 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; - - ret = exsltMathHighest(ns); - - xmlXPathFreeNodeSet(ns); - if (user != NULL) - xmlFreeNodeList((xmlNodePtr)user); - - xmlXPathReturnNodeSet(ctxt, ret); -} - -/** - * exsltMathLowest: - * @ns: a node-set - * - * Implements the EXSLT - Math lowest() function - * node-set math:lowest (node-set) - * - * Returns the nodes in the node-set whose value is the minimum value - * for the node-set. - */ -static xmlNodeSetPtr -exsltMathLowest (xmlNodeSetPtr ns) { - xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL); - double min, cur; - int i; - - if ((ns == NULL) || (ns->nodeNr == 0)) - return(ret); - - min = xmlXPathCastNodeToNumber(ns->nodeTab[0]); - if (xmlXPathIsNaN(min)) - return(ret); - else - xmlXPathNodeSetAddUnique(ret, ns->nodeTab[0]); - - for (i = 1; i < ns->nodeNr; i++) { - cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]); - if (xmlXPathIsNaN(cur)) { - xmlXPathEmptyNodeSet(ret); - return(ret); - } - if (cur > min) - continue; - if (cur < min) { - min = cur; - xmlXPathEmptyNodeSet(ret); - xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]); - continue; - } - xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]); - } - return(ret); -} - -/** - * exsltMathLowestFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathLowest for use by the XPath processor - */ -static void -exsltMathLowestFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr ns, ret; - void *user = NULL; - - - 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; - - ret = exsltMathLowest(ns); - - xmlXPathFreeNodeSet(ns); - if (user != NULL) - xmlFreeNodeList((xmlNodePtr)user); - - xmlXPathReturnNodeSet(ctxt, ret); -} - -/* math other functions */ - -/* constant values */ -#define EXSLT_PI (const xmlChar *) \ - "3.1415926535897932384626433832795028841971693993751" -#define EXSLT_E (const xmlChar *) \ - "2.71828182845904523536028747135266249775724709369996" -#define EXSLT_SQRRT2 (const xmlChar *) \ - "1.41421356237309504880168872420969807856967187537694" -#define EXSLT_LN2 (const xmlChar *) \ - "0.69314718055994530941723212145817656807550013436025" -#define EXSLT_LN10 (const xmlChar *) \ - "2.30258509299404568402" -#define EXSLT_LOG2E (const xmlChar *) \ - "1.4426950408889634074" -#define EXSLT_SQRT1_2 (const xmlChar *) \ - "0.70710678118654752440" - -/** - * exsltMathConstant - * @name: string - * @precision: number - * - * Implements the EXSLT - Math constant function: - * number math:constant(string, number) - * - * Returns a number value of the given constant with the given precision or - * xmlXPathNAN if name is unknown. - * The constants are PI, E, SQRRT2, LN2, LN10, LOG2E, and SQRT1_2 - */ -static double -exsltMathConstant (xmlChar *name, double precision) { - xmlChar *str; - double ret; - - if ((name == NULL) || (xmlXPathIsNaN(precision)) || (precision < 1.0)) { - return xmlXPathNAN; - } - - if (xmlStrEqual(name, BAD_CAST "PI")) { - int len = xmlStrlen(EXSLT_PI); - - if (precision <= len) - len = (int)precision; - - str = xmlStrsub(EXSLT_PI, 0, len); - - } else if (xmlStrEqual(name, BAD_CAST "E")) { - int len = xmlStrlen(EXSLT_E); - - if (precision <= len) - len = (int)precision; - - str = xmlStrsub(EXSLT_E, 0, len); - - } else if (xmlStrEqual(name, BAD_CAST "SQRRT2")) { - int len = xmlStrlen(EXSLT_SQRRT2); - - if (precision <= len) - len = (int)precision; - - str = xmlStrsub(EXSLT_SQRRT2, 0, len); - - } else if (xmlStrEqual(name, BAD_CAST "LN2")) { - int len = xmlStrlen(EXSLT_LN2); - - if (precision <= len) - len = (int)precision; - - str = xmlStrsub(EXSLT_LN2, 0, len); - - } else if (xmlStrEqual(name, BAD_CAST "LN10")) { - int len = xmlStrlen(EXSLT_LN10); - - if (precision <= len) - len = (int)precision; - - str = xmlStrsub(EXSLT_LN10, 0, len); - - } else if (xmlStrEqual(name, BAD_CAST "LOG2E")) { - int len = xmlStrlen(EXSLT_LOG2E); - - if (precision <= len) - len = (int)precision; - - str = xmlStrsub(EXSLT_LOG2E, 0, len); - - } else if (xmlStrEqual(name, BAD_CAST "SQRT1_2")) { - int len = xmlStrlen(EXSLT_SQRT1_2); - - if (precision <= len) - len = (int)precision; - - str = xmlStrsub(EXSLT_SQRT1_2, 0, len); - - } else { - str = NULL; - } - if (str == NULL) - return xmlXPathNAN; - ret = xmlXPathCastStringToNumber(str); - xmlFree(str); - return ret; -} - -/** - * exsltMathConstantFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathConstant for use by the XPath processor. - */ -static void -exsltMathConstantFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - xmlChar *name; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - name = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathConstant(name, ret); - if (name != NULL) - xmlFree(name); - - xmlXPathReturnNumber(ctxt, ret); -} - -#if defined(HAVE_STDLIB_H) && defined(RAND_MAX) - -/** - * exsltMathRandom: - * - * Implements the EXSLT - Math random() function: - * number math:random () - * - * Returns a random number between 0 and 1 inclusive. - */ -static double -exsltMathRandom (void) { - double ret; - int num; - - num = rand(); - ret = (double)num / (double)RAND_MAX; - return(ret); -} - -/** - * exsltMathRandomFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathRandom for use by the XPath processor. - */ -static void -exsltMathRandomFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 0) { - xmlXPathSetArityError(ctxt); - return; - } - - ret = exsltMathRandom(); - - xmlXPathReturnNumber(ctxt, ret); -} - -#endif /* defined(HAVE_STDLIB_H) && defined(RAND_MAX) */ - -#if HAVE_MATH_H - -/** - * exsltMathAbs: - * @num: a double - * - * Implements the EXSLT - Math abs() function: - * number math:abs (number) - * - * Returns the absolute value of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathAbs (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = fabs(num); - return(ret); -} - -/** - * exsltMathAbsFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathAbs for use by the XPath processor. - */ -static void -exsltMathAbsFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathAbs(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathSqrt: - * @num: a double - * - * Implements the EXSLT - Math sqrt() function: - * number math:sqrt (number) - * - * Returns the square root of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathSqrt (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = sqrt(num); - return(ret); -} - -/** - * exsltMathSqrtFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathSqrt for use by the XPath processor. - */ -static void -exsltMathSqrtFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathSqrt(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathPower: - * @base: a double - * @power: a double - * - * Implements the EXSLT - Math power() function: - * number math:power (number, number) - * - * Returns the power base and power arguments, or xmlXPathNAN - * if either @base or @power is Nan. - */ -static double -exsltMathPower (double base, double power) { - double ret; - - if ((xmlXPathIsNaN(base) || xmlXPathIsNaN(power))) - return(xmlXPathNAN); - ret = pow(base, power); - return(ret); -} - -/** - * exsltMathPower: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathPower for use by the XPath processor. - */ -static void -exsltMathPowerFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret, base; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - /* power */ - base = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathPower(base, ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathLog: - * @num: a double - * - * Implements the EXSLT - Math log() function: - * number math:log (number) - * - * Returns the natural log of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathLog (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = log(num); - return(ret); -} - -/** - * exsltMathLogFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathLog for use by the XPath processor. - */ -static void -exsltMathLogFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathLog(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathSin: - * @num: a double - * - * Implements the EXSLT - Math sin() function: - * number math:sin (number) - * - * Returns the sine of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathSin (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = sin(num); - return(ret); -} - -/** - * exsltMathSinFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathSin for use by the XPath processor. - */ -static void -exsltMathSinFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathSin(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathCos: - * @num: a double - * - * Implements the EXSLT - Math cos() function: - * number math:cos (number) - * - * Returns the cosine of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathCos (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = cos(num); - return(ret); -} - -/** - * exsltMathCosFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathCos for use by the XPath processor. - */ -static void -exsltMathCosFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathCos(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathTan: - * @num: a double - * - * Implements the EXSLT - Math tan() function: - * number math:tan (number) - * - * Returns the tangent of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathTan (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = tan(num); - return(ret); -} - -/** - * exsltMathTanFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathTan for use by the XPath processor. - */ -static void -exsltMathTanFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathTan(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathAsin: - * @num: a double - * - * Implements the EXSLT - Math asin() function: - * number math:asin (number) - * - * Returns the arc sine of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathAsin (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = asin(num); - return(ret); -} - -/** - * exsltMathAsinFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathAsin for use by the XPath processor. - */ -static void -exsltMathAsinFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathAsin(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathAcos: - * @num: a double - * - * Implements the EXSLT - Math acos() function: - * number math:acos (number) - * - * Returns the arc cosine of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathAcos (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = acos(num); - return(ret); -} - -/** - * exsltMathAcosFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathAcos for use by the XPath processor. - */ -static void -exsltMathAcosFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathAcos(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathAtan: - * @num: a double - * - * Implements the EXSLT - Math atan() function: - * number math:atan (number) - * - * Returns the arc tangent of the argument, or xmlXPathNAN if @num is Nan. - */ -static double -exsltMathAtan (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = atan(num); - return(ret); -} - -/** - * exsltMathAtanFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathAtan for use by the XPath processor. - */ -static void -exsltMathAtanFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathAtan(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathAtan2: - * @y: a double - * @x: a double - * - * Implements the EXSLT - Math atan2() function: - * number math:atan2 (number, number) - * - * Returns the arc tangent function of the y/x arguments, or xmlXPathNAN - * if either @y or @x is Nan. - */ -static double -exsltMathAtan2 (double y, double x) { - double ret; - - if ((xmlXPathIsNaN(y) || xmlXPathIsNaN(x))) - return(xmlXPathNAN); - ret = atan2(y, x); - return(ret); -} - -/** - * exsltMathAtan2Function: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathAtan2 for use by the XPath processor. - */ -static void -exsltMathAtan2Function (xmlXPathParserContextPtr ctxt, int nargs) { - double ret, x; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - x = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - /* y */ - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathAtan2(ret, x); - - xmlXPathReturnNumber(ctxt, ret); -} - -/** - * exsltMathExp: - * @num: a double - * - * Implements the EXSLT - Math exp() function: - * number math:exp (number) - * - * Returns the exponential function of the argument, or xmlXPathNAN if - * @num is Nan. - */ -static double -exsltMathExp (double num) { - double ret; - - if (xmlXPathIsNaN(num)) - return(xmlXPathNAN); - ret = exp(num); - return(ret); -} - -/** - * exsltMathExpFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #exsltMathExp for use by the XPath processor. - */ -static void -exsltMathExpFunction (xmlXPathParserContextPtr ctxt, int nargs) { - double ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - ret = xmlXPathPopNumber(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - ret = exsltMathExp(ret); - - xmlXPathReturnNumber(ctxt, ret); -} - -#endif /* HAVE_MATH_H */ - -/** - * exsltMathRegister: - * - * Registers the EXSLT - Math module - */ - -void -exsltMathRegister (void) { - xsltRegisterExtModuleFunction ((const xmlChar *) "min", - EXSLT_MATH_NAMESPACE, - exsltMathMinFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "max", - EXSLT_MATH_NAMESPACE, - exsltMathMaxFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "highest", - EXSLT_MATH_NAMESPACE, - exsltMathHighestFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "lowest", - EXSLT_MATH_NAMESPACE, - exsltMathLowestFunction); - /* register other math functions */ - xsltRegisterExtModuleFunction ((const xmlChar *) "constant", - EXSLT_MATH_NAMESPACE, - exsltMathConstantFunction); -#ifdef HAVE_STDLIB_H - xsltRegisterExtModuleFunction ((const xmlChar *) "random", - EXSLT_MATH_NAMESPACE, - exsltMathRandomFunction); -#endif -#if HAVE_MATH_H - xsltRegisterExtModuleFunction ((const xmlChar *) "abs", - EXSLT_MATH_NAMESPACE, - exsltMathAbsFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "sqrt", - EXSLT_MATH_NAMESPACE, - exsltMathSqrtFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "power", - EXSLT_MATH_NAMESPACE, - exsltMathPowerFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "log", - EXSLT_MATH_NAMESPACE, - exsltMathLogFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "sin", - EXSLT_MATH_NAMESPACE, - exsltMathSinFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "cos", - EXSLT_MATH_NAMESPACE, - exsltMathCosFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "tan", - EXSLT_MATH_NAMESPACE, - exsltMathTanFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "asin", - EXSLT_MATH_NAMESPACE, - exsltMathAsinFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "acos", - EXSLT_MATH_NAMESPACE, - exsltMathAcosFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "atan", - EXSLT_MATH_NAMESPACE, - exsltMathAtanFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "atan2", - EXSLT_MATH_NAMESPACE, - exsltMathAtan2Function); - xsltRegisterExtModuleFunction ((const xmlChar *) "exp", - EXSLT_MATH_NAMESPACE, - exsltMathExpFunction); -#endif -} - -/** - * exsltMathXpathCtxtRegister: - * - * Registers the EXSLT - Math module for use outside XSLT - */ -int -exsltMathXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix) -{ - if (ctxt - && prefix - && !xmlXPathRegisterNs(ctxt, - prefix, - (const xmlChar *) EXSLT_MATH_NAMESPACE) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "min", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathMinFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "max", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathMaxFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "highest", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathHighestFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "lowest", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathLowestFunction) -#ifdef HAVE_STDLIB_H - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "random", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathRandomFunction) -#endif -#if HAVE_MATH_H - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "abs", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathAbsFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "sqrt", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathSqrtFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "power", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathPowerFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "log", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathLogFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "sin", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathSinFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "cos", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathCosFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "tan", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathTanFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "asin", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathAsinFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "acos", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathAcosFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "atan", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathAtanFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "atan2", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathAtan2Function) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "exp", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathExpFunction) -#endif - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "constant", - (const xmlChar *) EXSLT_MATH_NAMESPACE, - exsltMathConstantFunction)) { - return 0; - } - return -1; -} diff --git a/libxslt/libexslt/saxon.c b/libxslt/libexslt/saxon.c deleted file mode 100644 index 7a2f63b..0000000 --- a/libxslt/libexslt/saxon.c +++ /dev/null @@ -1,313 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#endif - -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> -#include <libxml/parser.h> -#include <libxml/hash.h> - -#include <libxslt/xsltconfig.h> -#include <libxslt/xsltutils.h> -#include <libxslt/xsltInternals.h> -#include <libxslt/extensions.h> - -#include "exslt.h" - -/** - * exsltSaxonInit: - * @ctxt: an XSLT transformation context - * @URI: the namespace URI for the extension - * - * Initializes the SAXON module. - * - * Returns the data for this transformation - */ -static xmlHashTablePtr -exsltSaxonInit (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, - const xmlChar *URI ATTRIBUTE_UNUSED) { - return xmlHashCreate(1); -} - -/** - * exsltSaxonShutdown: - * @ctxt: an XSLT transformation context - * @URI: the namespace URI for the extension - * @data: the module data to free up - * - * Shutdown the SAXON extension module - */ -static void -exsltSaxonShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, - const xmlChar *URI ATTRIBUTE_UNUSED, - xmlHashTablePtr data) { - xmlHashFree(data, (xmlHashDeallocator) xmlXPathFreeCompExpr); -} - - -/** - * exsltSaxonExpressionFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * The supplied string must contain an XPath expression. The result of - * the function is a stored expression, which may be supplied as an - * argument to other extension functions such as saxon:eval(), - * saxon:sum() and saxon:distinct(). The result of the expression will - * usually depend on the current node. The expression may contain - * references to variables that are in scope at the point where - * saxon:expression() is called: these variables will be replaced in - * the stored expression with the values they take at the time - * saxon:expression() is called, not the values of the variables at - * the time the stored expression is evaluated. Similarly, if the - * expression contains namespace prefixes, these are interpreted in - * terms of the namespace declarations in scope at the point where the - * saxon:expression() function is called, not those in scope where the - * stored expression is evaluated. - * - * TODO: current implementation doesn't conform to SAXON behaviour - * regarding context and namespaces. - */ -static void -exsltSaxonExpressionFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlChar *arg; - xmlXPathCompExprPtr ret; - xmlHashTablePtr hash; - xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - - arg = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt) || (arg == NULL)) { - xmlXPathSetTypeError(ctxt); - return; - } - - hash = (xmlHashTablePtr) xsltGetExtData(tctxt, - ctxt->context->functionURI); - - ret = xmlHashLookup(hash, arg); - - if (ret == NULL) { - ret = xmlXPathCompile(arg); - if (ret == NULL) { - xmlFree(arg); - xmlXPathSetError(ctxt, XPATH_EXPR_ERROR); - return; - } - xmlHashAddEntry(hash, arg, (void *) ret); - } - - xmlFree(arg); - - xmlXPathReturnExternal(ctxt, ret); -} - -/** - * exsltSaxonEvalFunction: - * @ctxt: an XPath parser context - * @nargs: number of arguments - * - * Implements de SAXON eval() function: - * object saxon:eval (saxon:stored-expression) - * Returns the result of evaluating the supplied stored expression. - * A stored expression may be obtained as the result of calling - * the saxon:expression() function. - * The stored expression is evaluated in the current context, that - * is, the context node is the current node, and the context position - * and context size are the same as the result of calling position() - * or last() respectively. - */ -static void -exsltSaxonEvalFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathCompExprPtr expr; - xmlXPathObjectPtr ret; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - - if (!xmlXPathStackIsExternal(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - expr = (xmlXPathCompExprPtr) xmlXPathPopExternal(ctxt); - - ret = xmlXPathCompiledEval(expr, ctxt->context); - if (ret == NULL) { - xmlXPathSetError(ctxt, XPATH_EXPR_ERROR); - return; - } - - valuePush(ctxt, ret); -} - -/** - * exsltSaxonEvaluateFunction: - * @ctxt: an XPath parser context - * @nargs: number of arguments - * - * Implements the SAXON evaluate() function - * object saxon:evaluate (string) - * The supplied string must contain an XPath expression. The result of - * the function is the result of evaluating the XPath expression. This - * is useful where an expression needs to be constructed at run-time or - * passed to the stylesheet as a parameter, for example where the sort - * key is determined dynamically. The context for the expression (e.g. - * which variables and namespaces are available) is exactly the same as - * if the expression were written explicitly at this point in the - * stylesheet. The function saxon:evaluate(string) is shorthand for - * saxon:eval(saxon:expression(string)). - */ -static void -exsltSaxonEvaluateFunction (xmlXPathParserContextPtr ctxt, int nargs) { - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - - exsltSaxonExpressionFunction(ctxt, 1); - exsltSaxonEvalFunction(ctxt, 1); -} - -/** - * exsltSaxonSystemIdFunction: - * @ctxt: an XPath parser context - * @nargs: number of arguments - * - * Implements the SAXON systemId() function - * string saxon:systemId () - * This function returns the system ID of the document being styled. - */ -static void -exsltSaxonSystemIdFunction(xmlXPathParserContextPtr ctxt, int nargs) -{ - if (ctxt == NULL) - return; - if (nargs != 0) { - xmlXPathSetArityError(ctxt); - return; - } - - if ((ctxt->context) && (ctxt->context->doc) && - (ctxt->context->doc->URL)) - valuePush(ctxt, xmlXPathNewString(ctxt->context->doc->URL)); - else - valuePush(ctxt, xmlXPathNewString(BAD_CAST "")); -} - -/** - * exsltSaxonLineNumberFunction: - * @ctxt: an XPath parser context - * @nargs: number of arguments - * - * Implements the SAXON line-number() function - * integer saxon:line-number() - * - * This returns the line number of the context node in the source document - * within the entity that contains it. There are no arguments. If line numbers - * are not maintained for the current document, the function returns -1. (To - * ensure that line numbers are maintained, use the -l option on the command - * line) - * - * The extension has been extended to have the following form: - * integer saxon:line-number([node-set-1]) - * If a node-set is given, this extension will return the line number of the - * node in the argument node-set that is first in document order. - */ -static void -exsltSaxonLineNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodePtr cur = NULL; - xmlXPathObjectPtr obj = NULL; - long lineNo = -1; - - if (nargs == 0) { - cur = ctxt->context->node; - } else if (nargs == 1) { - xmlNodeSetPtr nodelist; - int i; - - if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, - "saxon:line-number() : invalid arg expecting a node-set\n"); - ctxt->error = XPATH_INVALID_TYPE; - return; - } - - obj = valuePop(ctxt); - nodelist = obj->nodesetval; - if ((nodelist != NULL) && (nodelist->nodeNr > 0)) { - cur = nodelist->nodeTab[0]; - for (i = 1;i < nodelist->nodeNr;i++) { - int ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); - if (ret == -1) - cur = nodelist->nodeTab[i]; - } - } - } else { - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, - "saxon:line-number() : invalid number of args %d\n", - nargs); - ctxt->error = XPATH_INVALID_ARITY; - return; - } - - if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL)) { - /* - * The XPath module sets the owner element of a ns-node on - * the ns->next field. - */ - cur = (xmlNodePtr) ((xmlNsPtr) cur)->next; - if (cur == NULL || cur->type != XML_ELEMENT_NODE) { - xsltGenericError(xsltGenericErrorContext, - "Internal error in exsltSaxonLineNumberFunction: " - "Cannot retrieve the doc of a namespace node.\n"); - cur = NULL; - } - } - - if (cur != NULL) - lineNo = xmlGetLineNo(cur); - - valuePush(ctxt, xmlXPathNewFloat(lineNo)); - - xmlXPathFreeObject(obj); -} - -/** - * exsltSaxonRegister: - * - * Registers the SAXON extension module - */ -void -exsltSaxonRegister (void) { - xsltRegisterExtModule (SAXON_NAMESPACE, - (xsltExtInitFunction) exsltSaxonInit, - (xsltExtShutdownFunction) exsltSaxonShutdown); - xsltRegisterExtModuleFunction((const xmlChar *) "expression", - SAXON_NAMESPACE, - exsltSaxonExpressionFunction); - xsltRegisterExtModuleFunction((const xmlChar *) "eval", - SAXON_NAMESPACE, - exsltSaxonEvalFunction); - xsltRegisterExtModuleFunction((const xmlChar *) "evaluate", - SAXON_NAMESPACE, - exsltSaxonEvaluateFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "line-number", - SAXON_NAMESPACE, - exsltSaxonLineNumberFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "systemId", - SAXON_NAMESPACE, - exsltSaxonSystemIdFunction); -} diff --git a/libxslt/libexslt/sets.c b/libxslt/libexslt/sets.c deleted file mode 100644 index a5a7913..0000000 --- a/libxslt/libexslt/sets.c +++ /dev/null @@ -1,334 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#endif - -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -#include <libxslt/xsltutils.h> -#include <libxslt/xsltInternals.h> -#include <libxslt/extensions.h> - -#include "exslt.h" - -/** - * exsltSetsDifferenceFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #xmlXPathDifference for use by the XPath processor - */ -static void -exsltSetsDifferenceFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr arg1, arg2, ret; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - - arg2 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - arg1 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - ret = xmlXPathDifference(arg1, arg2); - - if (ret != arg1) - xmlXPathFreeNodeSet(arg1); - xmlXPathFreeNodeSet(arg2); - - xmlXPathReturnNodeSet(ctxt, ret); -} - -/** - * exsltSetsIntersectionFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #xmlXPathIntersection for use by the XPath processor - */ -static void -exsltSetsIntersectionFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr arg1, arg2, ret; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - - arg2 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - arg1 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - ret = xmlXPathIntersection(arg1, arg2); - - xmlXPathFreeNodeSet(arg1); - xmlXPathFreeNodeSet(arg2); - - xmlXPathReturnNodeSet(ctxt, ret); -} - -/** - * exsltSetsDistinctFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #xmlXPathDistinct for use by the XPath processor - */ -static void -exsltSetsDistinctFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr obj; - xmlNodeSetPtr ns, ret; - int boolval = 0; - void *user = NULL; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - - if (ctxt->value != NULL) { - boolval = ctxt->value->boolval; - user = ctxt->value->user; - ctxt->value->boolval = 0; - ctxt->value->user = NULL; - } - ns = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - - /* !!! must be sorted !!! */ - ret = xmlXPathDistinctSorted(ns); - - if (ret != ns) - xmlXPathFreeNodeSet(ns); - - obj = xmlXPathWrapNodeSet(ret); - obj->user = user; - obj->boolval = boolval; - valuePush((ctxt), obj); -} - -/** - * exsltSetsHasSameNodesFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #xmlXPathHasSameNodes for use by the XPath processor - */ -static void -exsltSetsHasSameNodesFunction (xmlXPathParserContextPtr ctxt, - int nargs) { - xmlNodeSetPtr arg1, arg2; - int ret; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - - arg2 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - arg1 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - ret = xmlXPathHasSameNodes(arg1, arg2); - - xmlXPathFreeNodeSet(arg1); - xmlXPathFreeNodeSet(arg2); - - xmlXPathReturnBoolean(ctxt, ret); -} - -/** - * exsltSetsLeadingFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #xmlXPathLeading for use by the XPath processor - */ -static void -exsltSetsLeadingFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr arg1, arg2, ret; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - - arg2 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - arg1 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - /* If the second node set is empty, then the first node set is - * returned. - */ - if (xmlXPathNodeSetIsEmpty(arg2)) { - xmlXPathReturnNodeSet(ctxt, arg1); - - xmlXPathFreeNodeSet(arg2); - - return; - } - /* !!! must be sorted */ - ret = xmlXPathNodeLeadingSorted(arg1, xmlXPathNodeSetItem(arg2, 0)); - - xmlXPathFreeNodeSet(arg1); - xmlXPathFreeNodeSet(arg2); - - xmlXPathReturnNodeSet(ctxt, ret); -} - -/** - * exsltSetsTrailingFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Wraps #xmlXPathTrailing for use by the XPath processor - */ -static void -exsltSetsTrailingFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlNodeSetPtr arg1, arg2, ret; - - if (nargs != 2) { - xmlXPathSetArityError(ctxt); - return; - } - - arg2 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - arg1 = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - /* If the second node set is empty, then the first node set is - * returned. - */ - if (xmlXPathNodeSetIsEmpty(arg2)) { - xmlXPathReturnNodeSet(ctxt, arg1); - - xmlXPathFreeNodeSet(arg2); - - return; - } - /* !!! mist be sorted */ - ret = xmlXPathNodeTrailingSorted(arg1, xmlXPathNodeSetItem(arg2, 0)); - - xmlXPathFreeNodeSet(arg1); - xmlXPathFreeNodeSet(arg2); - - xmlXPathReturnNodeSet(ctxt, ret); -} - -/** - * exsltSetsRegister: - * - * Registers the EXSLT - Sets module - */ - -void -exsltSetsRegister (void) { - xsltRegisterExtModuleFunction ((const xmlChar *) "difference", - EXSLT_SETS_NAMESPACE, - exsltSetsDifferenceFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "intersection", - EXSLT_SETS_NAMESPACE, - exsltSetsIntersectionFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "distinct", - EXSLT_SETS_NAMESPACE, - exsltSetsDistinctFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "has-same-node", - EXSLT_SETS_NAMESPACE, - exsltSetsHasSameNodesFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "leading", - EXSLT_SETS_NAMESPACE, - exsltSetsLeadingFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "trailing", - EXSLT_SETS_NAMESPACE, - exsltSetsTrailingFunction); -} - -/** - * exsltSetsXpathCtxtRegister: - * - * Registers the EXSLT - Sets module for use outside XSLT - */ -int -exsltSetsXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix) -{ - if (ctxt - && prefix - && !xmlXPathRegisterNs(ctxt, - prefix, - (const xmlChar *) EXSLT_SETS_NAMESPACE) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "difference", - (const xmlChar *) EXSLT_SETS_NAMESPACE, - exsltSetsDifferenceFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "intersection", - (const xmlChar *) EXSLT_SETS_NAMESPACE, - exsltSetsIntersectionFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "distinct", - (const xmlChar *) EXSLT_SETS_NAMESPACE, - exsltSetsDistinctFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "has-same-node", - (const xmlChar *) EXSLT_SETS_NAMESPACE, - exsltSetsHasSameNodesFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "leading", - (const xmlChar *) EXSLT_SETS_NAMESPACE, - exsltSetsLeadingFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "trailing", - (const xmlChar *) EXSLT_SETS_NAMESPACE, - exsltSetsTrailingFunction)) { - return 0; - } - return -1; -} diff --git a/libxslt/libexslt/strings.c b/libxslt/libexslt/strings.c deleted file mode 100644 index f5f2d3c..0000000 --- a/libxslt/libexslt/strings.c +++ /dev/null @@ -1,847 +0,0 @@ -#define IN_LIBEXSLT -#include "libexslt/libexslt.h" - -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) -#include <win32config.h> -#else -#include "config.h" -#endif - -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> -#include <libxml/parser.h> -#include <libxml/encoding.h> -#include <libxml/uri.h> - -#include <libxslt/xsltconfig.h> -#include <libxslt/xsltutils.h> -#include <libxslt/xsltInternals.h> -#include <libxslt/extensions.h> - -#include "exslt.h" - -/** - * exsltStrTokenizeFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Splits up a string on the characters of the delimiter string and returns a - * node set of token elements, each containing one token from the string. - */ -static void -exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs) -{ - xsltTransformContextPtr tctxt; - xmlChar *str, *delimiters, *cur; - const xmlChar *token, *delimiter; - xmlNodePtr node; - xmlDocPtr container; - xmlXPathObjectPtr ret = NULL; - int clen; - - if ((nargs < 1) || (nargs > 2)) { - xmlXPathSetArityError(ctxt); - return; - } - - if (nargs == 2) { - delimiters = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - } else { - delimiters = xmlStrdup((const xmlChar *) "\t\r\n "); - } - if (delimiters == NULL) - return; - - str = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt) || (str == NULL)) { - xmlFree(delimiters); - return; - } - - /* Return a result tree fragment */ - tctxt = xsltXPathGetTransformContext(ctxt); - if (tctxt == NULL) { - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, - "exslt:tokenize : internal error tctxt == NULL\n"); - goto fail; - } - - container = xsltCreateRVT(tctxt); - if (container != NULL) { - xsltRegisterLocalRVT(tctxt, container); - ret = xmlXPathNewNodeSet(NULL); - if (ret != NULL) { - for (cur = str, token = str; *cur != 0; cur += clen) { - clen = xmlUTF8Size(cur); - if (*delimiters == 0) { /* empty string case */ - xmlChar ctmp; - ctmp = *(cur+clen); - *(cur+clen) = 0; - node = xmlNewDocRawNode(container, NULL, - (const xmlChar *) "token", cur); - xmlAddChild((xmlNodePtr) container, node); - xmlXPathNodeSetAddUnique(ret->nodesetval, node); - *(cur+clen) = ctmp; /* restore the changed byte */ - token = cur + clen; - } else for (delimiter = delimiters; *delimiter != 0; - delimiter += xmlUTF8Size(delimiter)) { - if (!xmlUTF8Charcmp(cur, delimiter)) { - if (cur == token) { - /* discard empty tokens */ - token = cur + clen; - break; - } - *cur = 0; /* terminate the token */ - node = xmlNewDocRawNode(container, NULL, - (const xmlChar *) "token", token); - xmlAddChild((xmlNodePtr) container, node); - xmlXPathNodeSetAddUnique(ret->nodesetval, node); - *cur = *delimiter; /* restore the changed byte */ - token = cur + clen; - break; - } - } - } - if (token != cur) { - node = xmlNewDocRawNode(container, NULL, - (const xmlChar *) "token", token); - xmlAddChild((xmlNodePtr) container, node); - xmlXPathNodeSetAddUnique(ret->nodesetval, node); - } - /* - * Mark it as a function result in order to avoid garbage - * collecting of tree fragments - */ - xsltExtensionInstructionResultRegister(tctxt, ret); - } - } - -fail: - if (str != NULL) - xmlFree(str); - if (delimiters != NULL) - xmlFree(delimiters); - if (ret != NULL) - valuePush(ctxt, ret); - else - valuePush(ctxt, xmlXPathNewNodeSet(NULL)); -} - -/** - * exsltStrSplitFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Splits up a string on a delimiting string and returns a node set of token - * elements, each containing one token from the string. - */ -static void -exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) { - xsltTransformContextPtr tctxt; - xmlChar *str, *delimiter, *cur; - const xmlChar *token; - xmlNodePtr node; - xmlDocPtr container; - xmlXPathObjectPtr ret = NULL; - int delimiterLength; - - if ((nargs < 1) || (nargs > 2)) { - xmlXPathSetArityError(ctxt); - return; - } - - if (nargs == 2) { - delimiter = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt)) - return; - } else { - delimiter = xmlStrdup((const xmlChar *) " "); - } - if (delimiter == NULL) - return; - delimiterLength = xmlStrlen (delimiter); - - str = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt) || (str == NULL)) { - xmlFree(delimiter); - return; - } - - /* Return a result tree fragment */ - tctxt = xsltXPathGetTransformContext(ctxt); - if (tctxt == NULL) { - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, - "exslt:tokenize : internal error tctxt == NULL\n"); - goto fail; - } - - /* - * OPTIMIZE TODO: We are creating an xmlDoc for every split! - */ - container = xsltCreateRVT(tctxt); - if (container != NULL) { - xsltRegisterLocalRVT(tctxt, container); - ret = xmlXPathNewNodeSet(NULL); - if (ret != NULL) { - for (cur = str, token = str; *cur != 0; cur++) { - if (delimiterLength == 0) { - if (cur != token) { - xmlChar tmp = *cur; - *cur = 0; - node = xmlNewDocRawNode(container, NULL, - (const xmlChar *) "token", token); - xmlAddChild((xmlNodePtr) container, node); - xmlXPathNodeSetAddUnique(ret->nodesetval, node); - *cur = tmp; - token++; - } - } - else if (!xmlStrncasecmp(cur, delimiter, delimiterLength)) { - if (cur == token) { - /* discard empty tokens */ - cur = cur + delimiterLength - 1; - token = cur + 1; - continue; - } - *cur = 0; - node = xmlNewDocRawNode(container, NULL, - (const xmlChar *) "token", token); - xmlAddChild((xmlNodePtr) container, node); - xmlXPathNodeSetAddUnique(ret->nodesetval, node); - *cur = *delimiter; - cur = cur + delimiterLength - 1; - token = cur + 1; - } - } - if (token != cur) { - node = xmlNewDocRawNode(container, NULL, - (const xmlChar *) "token", token); - xmlAddChild((xmlNodePtr) container, node); - xmlXPathNodeSetAddUnique(ret->nodesetval, node); - } - /* - * Mark it as a function result in order to avoid garbage - * collecting of tree fragments - */ - xsltExtensionInstructionResultRegister(tctxt, ret); - } - } - -fail: - if (str != NULL) - xmlFree(str); - if (delimiter != NULL) - xmlFree(delimiter); - if (ret != NULL) - valuePush(ctxt, ret); - else - valuePush(ctxt, xmlXPathNewNodeSet(NULL)); -} - -/** - * exsltStrEncodeUriFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * URI-Escapes a string - */ -static void -exsltStrEncodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) { - int escape_all = 1, str_len = 0; - xmlChar *str = NULL, *ret = NULL, *tmp; - - if ((nargs < 2) || (nargs > 3)) { - xmlXPathSetArityError(ctxt); - return; - } - - if (nargs >= 3) { - /* check for UTF-8 if encoding was explicitly given; - we don't support anything else yet */ - tmp = xmlXPathPopString(ctxt); - if (xmlUTF8Strlen(tmp) != 5 || xmlStrcmp((const xmlChar *)"UTF-8",tmp)) { - xmlXPathReturnEmptyString(ctxt); - xmlFree(tmp); - return; - } - xmlFree(tmp); - } - - escape_all = xmlXPathPopBoolean(ctxt); - - str = xmlXPathPopString(ctxt); - str_len = xmlUTF8Strlen(str); - - if (str_len == 0) { - xmlXPathReturnEmptyString(ctxt); - xmlFree(str); - return; - } - - ret = xmlURIEscapeStr(str,(const xmlChar *)(escape_all?"-_.!~*'()":"-_.!~*'();/?:@&=+$,[]")); - xmlXPathReturnString(ctxt, ret); - - if (str != NULL) - xmlFree(str); -} - -/** - * exsltStrDecodeUriFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * reverses URI-Escaping of a string - */ -static void -exsltStrDecodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) { - int str_len = 0; - xmlChar *str = NULL, *ret = NULL, *tmp; - - if ((nargs < 1) || (nargs > 2)) { - xmlXPathSetArityError(ctxt); - return; - } - - if (nargs >= 2) { - /* check for UTF-8 if encoding was explicitly given; - we don't support anything else yet */ - tmp = xmlXPathPopString(ctxt); - if (xmlUTF8Strlen(tmp) != 5 || xmlStrcmp((const xmlChar *)"UTF-8",tmp)) { - xmlXPathReturnEmptyString(ctxt); - xmlFree(tmp); - return; - } - xmlFree(tmp); - } - - str = xmlXPathPopString(ctxt); - str_len = xmlUTF8Strlen(str); - - if (str_len == 0) { - xmlXPathReturnEmptyString(ctxt); - xmlFree(str); - return; - } - - ret = (xmlChar *) xmlURIUnescapeString((const char *)str,0,NULL); - if (!xmlCheckUTF8(ret)) { - /* FIXME: instead of throwing away the whole URI, we should - only discard the invalid sequence(s). How to do that? */ - xmlXPathReturnEmptyString(ctxt); - xmlFree(str); - xmlFree(ret); - return; - } - - xmlXPathReturnString(ctxt, ret); - - if (str != NULL) - xmlFree(str); -} - -/** - * exsltStrPaddingFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Creates a padding string of a certain length. - */ -static void -exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) { - int number, str_len = 0, str_size = 0; - xmlChar *str = NULL, *ret = NULL; - - if ((nargs < 1) || (nargs > 2)) { - xmlXPathSetArityError(ctxt); - return; - } - - if (nargs == 2) { - str = xmlXPathPopString(ctxt); - str_len = xmlUTF8Strlen(str); - str_size = xmlStrlen(str); - } - if (str_len == 0) { - if (str != NULL) xmlFree(str); - str = xmlStrdup((const xmlChar *) " "); - str_len = 1; - str_size = 1; - } - - number = (int) xmlXPathPopNumber(ctxt); - - if (number <= 0) { - xmlXPathReturnEmptyString(ctxt); - xmlFree(str); - return; - } - - while (number >= str_len) { - ret = xmlStrncat(ret, str, str_size); - number -= str_len; - } - if (number > 0) { - str_size = xmlUTF8Strsize(str, number); - ret = xmlStrncat(ret, str, str_size); - } - - xmlXPathReturnString(ctxt, ret); - - if (str != NULL) - xmlFree(str); -} - -/** - * exsltStrAlignFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Aligns a string within another string. - */ -static void -exsltStrAlignFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlChar *str, *padding, *alignment, *ret; - int str_l, padding_l; - - if ((nargs < 2) || (nargs > 3)) { - xmlXPathSetArityError(ctxt); - return; - } - - if (nargs == 3) - alignment = xmlXPathPopString(ctxt); - else - alignment = NULL; - - padding = xmlXPathPopString(ctxt); - str = xmlXPathPopString(ctxt); - - str_l = xmlUTF8Strlen (str); - padding_l = xmlUTF8Strlen (padding); - - if (str_l == padding_l) { - xmlXPathReturnString (ctxt, str); - xmlFree(padding); - xmlFree(alignment); - return; - } - - if (str_l > padding_l) { - ret = xmlUTF8Strndup (str, padding_l); - } else { - if (xmlStrEqual(alignment, (const xmlChar *) "right")) { - ret = xmlUTF8Strndup (padding, padding_l - str_l); - ret = xmlStrcat (ret, str); - } else if (xmlStrEqual(alignment, (const xmlChar *) "center")) { - int left = (padding_l - str_l) / 2; - int right_start; - - ret = xmlUTF8Strndup (padding, left); - ret = xmlStrcat (ret, str); - - right_start = xmlUTF8Strsize (padding, left + str_l); - ret = xmlStrcat (ret, padding + right_start); - } else { - int str_s; - - str_s = xmlUTF8Strsize(padding, str_l); - ret = xmlStrdup (str); - ret = xmlStrcat (ret, padding + str_s); - } - } - - xmlXPathReturnString (ctxt, ret); - - xmlFree(str); - xmlFree(padding); - xmlFree(alignment); -} - -/** - * exsltStrConcatFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Takes a node set and returns the concatenation of the string values - * of the nodes in that node set. If the node set is empty, it - * returns an empty string. - */ -static void -exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr obj; - xmlChar *ret = NULL; - int i; - - if (nargs != 1) { - xmlXPathSetArityError(ctxt); - return; - } - - if (!xmlXPathStackIsNodeSet(ctxt)) { - xmlXPathSetTypeError(ctxt); - return; - } - - obj = valuePop (ctxt); - - if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) { - xmlXPathReturnEmptyString(ctxt); - return; - } - - for (i = 0; i < obj->nodesetval->nodeNr; i++) { - xmlChar *tmp; - tmp = xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]); - - ret = xmlStrcat (ret, tmp); - - xmlFree(tmp); - } - - xmlXPathFreeObject (obj); - - xmlXPathReturnString(ctxt, ret); -} - -/** - * exsltStrReturnString: - * @ctxt: an XPath parser context - * @str: a string - * @len: length of string - * - * Returns a string as a node set. - */ -static int -exsltStrReturnString(xmlXPathParserContextPtr ctxt, const xmlChar *str, - int len) -{ - xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); - xmlDocPtr container; - xmlNodePtr text_node; - xmlXPathObjectPtr ret; - - container = xsltCreateRVT(tctxt); - if (container == NULL) { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - return(-1); - } - xsltRegisterLocalRVT(tctxt, container); - - text_node = xmlNewTextLen(str, len); - if (text_node == NULL) { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - return(-1); - } - xmlAddChild((xmlNodePtr) container, text_node); - - ret = xmlXPathNewNodeSet(text_node); - if (ret == NULL) { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - return(-1); - } - - xsltExtensionInstructionResultRegister(tctxt, ret); - valuePush(ctxt, ret); - - return(0); -} - -/** - * exsltStrReplaceFunction: - * @ctxt: an XPath parser context - * @nargs: the number of arguments - * - * Takes a string, and two node sets and returns the string with all strings in - * the first node set replaced by all strings in the second node set. - */ -static void -exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { - int i, i_empty, n, slen0, rlen0, *slen, *rlen; - void *mem = NULL; - const xmlChar *src, *start; - xmlChar *string, *search_str = NULL, *replace_str = NULL; - xmlChar **search, **replace; - xmlNodeSetPtr search_set = NULL, replace_set = NULL; - xmlBufferPtr buf; - - if (nargs != 3) { - xmlXPathSetArityError(ctxt); - return; - } - - /* get replace argument */ - - if (!xmlXPathStackIsNodeSet(ctxt)) - replace_str = xmlXPathPopString(ctxt); - else - replace_set = xmlXPathPopNodeSet(ctxt); - - if (xmlXPathCheckError(ctxt)) - goto fail_replace; - - /* get search argument */ - - if (!xmlXPathStackIsNodeSet(ctxt)) { - search_str = xmlXPathPopString(ctxt); - n = 1; - } - else { - search_set = xmlXPathPopNodeSet(ctxt); - n = search_set != NULL ? search_set->nodeNr : 0; - } - - if (xmlXPathCheckError(ctxt)) - goto fail_search; - - /* get string argument */ - - string = xmlXPathPopString(ctxt); - if (xmlXPathCheckError(ctxt)) - goto fail_string; - - /* check for empty search node list */ - - if (n <= 0) { - exsltStrReturnString(ctxt, string, xmlStrlen(string)); - goto done_empty_search; - } - - /* allocate memory for string pointer and length arrays */ - - if (n == 1) { - search = &search_str; - replace = &replace_str; - slen = &slen0; - rlen = &rlen0; - } - else { - mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int))); - if (mem == NULL) { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - goto fail_malloc; - } - search = (xmlChar **) mem; - replace = search + n; - slen = (int *) (replace + n); - rlen = slen + n; - } - - /* process arguments */ - - i_empty = -1; - - for (i=0; i<n; ++i) { - if (search_set != NULL) { - search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]); - if (search[i] == NULL) { - n = i; - goto fail_process_args; - } - } - - slen[i] = xmlStrlen(search[i]); - if (i_empty < 0 && slen[i] == 0) - i_empty = i; - - if (replace_set != NULL) { - if (i < replace_set->nodeNr) { - replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]); - if (replace[i] == NULL) { - n = i + 1; - goto fail_process_args; - } - } - else - replace[i] = NULL; - } - else { - if (i == 0) - replace[i] = replace_str; - else - replace[i] = NULL; - } - - if (replace[i] == NULL) - rlen[i] = 0; - else - rlen[i] = xmlStrlen(replace[i]); - } - - if (i_empty >= 0 && rlen[i_empty] == 0) - i_empty = -1; - - /* replace operation */ - - buf = xmlBufferCreate(); - if (buf == NULL) { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - goto fail_buffer; - } - src = string; - start = string; - - while (*src != 0) { - int max_len = 0, i_match = 0; - - for (i=0; i<n; ++i) { - if (*src == search[i][0] && - slen[i] > max_len && - xmlStrncmp(src, search[i], slen[i]) == 0) - { - i_match = i; - max_len = slen[i]; - } - } - - if (max_len == 0) { - if (i_empty >= 0 && start < src) { - if (xmlBufferAdd(buf, start, src - start) || - xmlBufferAdd(buf, replace[i_empty], rlen[i_empty])) - { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - goto fail_buffer_add; - } - start = src; - } - - src += xmlUTF8Size(src); - } - else { - if ((start < src && - xmlBufferAdd(buf, start, src - start)) || - (rlen[i_match] && - xmlBufferAdd(buf, replace[i_match], rlen[i_match]))) - { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - goto fail_buffer_add; - } - - src += slen[i_match]; - start = src; - } - } - - if (start < src && xmlBufferAdd(buf, start, src - start)) { - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); - goto fail_buffer_add; - } - - /* create result node set */ - - exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf)); - - /* clean up */ - -fail_buffer_add: - xmlBufferFree(buf); - -fail_buffer: -fail_process_args: - if (search_set != NULL) { - for (i=0; i<n; ++i) - xmlFree(search[i]); - } - if (replace_set != NULL) { - for (i=0; i<n; ++i) { - if (replace[i] != NULL) - xmlFree(replace[i]); - } - } - - if (mem != NULL) - xmlFree(mem); - -fail_malloc: -done_empty_search: - xmlFree(string); - -fail_string: - if (search_set != NULL) - xmlXPathFreeNodeSet(search_set); - else - xmlFree(search_str); - -fail_search: - if (replace_set != NULL) - xmlXPathFreeNodeSet(replace_set); - else - xmlFree(replace_str); - -fail_replace: - return; -} - -/** - * exsltStrRegister: - * - * Registers the EXSLT - Strings module - */ - -void -exsltStrRegister (void) { - xsltRegisterExtModuleFunction ((const xmlChar *) "tokenize", - EXSLT_STRINGS_NAMESPACE, - exsltStrTokenizeFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "split", - EXSLT_STRINGS_NAMESPACE, - exsltStrSplitFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "encode-uri", - EXSLT_STRINGS_NAMESPACE, - exsltStrEncodeUriFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "decode-uri", - EXSLT_STRINGS_NAMESPACE, - exsltStrDecodeUriFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "padding", - EXSLT_STRINGS_NAMESPACE, - exsltStrPaddingFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "align", - EXSLT_STRINGS_NAMESPACE, - exsltStrAlignFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "concat", - EXSLT_STRINGS_NAMESPACE, - exsltStrConcatFunction); - xsltRegisterExtModuleFunction ((const xmlChar *) "replace", - EXSLT_STRINGS_NAMESPACE, - exsltStrReplaceFunction); -} - -/** - * exsltStrXpathCtxtRegister: - * - * Registers the EXSLT - Strings module for use outside XSLT - */ -int -exsltStrXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix) -{ - if (ctxt - && prefix - && !xmlXPathRegisterNs(ctxt, - prefix, - (const xmlChar *) EXSLT_STRINGS_NAMESPACE) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "encode-uri", - (const xmlChar *) EXSLT_STRINGS_NAMESPACE, - exsltStrEncodeUriFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "decode-uri", - (const xmlChar *) EXSLT_STRINGS_NAMESPACE, - exsltStrDecodeUriFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "padding", - (const xmlChar *) EXSLT_STRINGS_NAMESPACE, - exsltStrPaddingFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "align", - (const xmlChar *) EXSLT_STRINGS_NAMESPACE, - exsltStrAlignFunction) - && !xmlXPathRegisterFuncNS(ctxt, - (const xmlChar *) "concat", - (const xmlChar *) EXSLT_STRINGS_NAMESPACE, - exsltStrConcatFunction)) { - return 0; - } - return -1; -} |