summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2008-08-01 08:27:18 +0000
committerDaniel Veillard <veillard@src.gnome.org>2008-08-01 08:27:18 +0000
commit79ab294f6f75042e12cbf96ed5dded0ae622a650 (patch)
treee4bd73968cc5a736d9651db5ed8df33fede681ed
parenta85673c19dcc57071c0ade9208a09da76f8d16f5 (diff)
downloadlibxslt-79ab294f6f75042e12cbf96ed5dded0ae622a650.tar.gz
big patch from Roumen Petrov finishing xsl:sort lang support with many
* libxslt/xsltconfig.h.in libxslt/xslt.c libxslt/extensions.c libxslt/xsltlocale.c libxslt/preproc.c libxslt/xsltutils.c libxslt/xsltlocale.h libxslt/win32config.h configure.in config.h.in win32/configure.js: big patch from Roumen Petrov finishing xsl:sort lang support with many portability issues fixed and feedback from Nick Wellnhofer and Rob Richards Daniel svn path=/trunk/; revision=1488
-rw-r--r--ChangeLog12
-rw-r--r--config.h.in3
-rw-r--r--configure.in44
-rw-r--r--libxslt/extensions.c2
-rw-r--r--libxslt/preproc.c6
-rw-r--r--libxslt/win32config.h2
-rw-r--r--libxslt/xslt.c6
-rw-r--r--libxslt/xsltconfig.h.in6
-rw-r--r--libxslt/xsltlocale.c347
-rw-r--r--libxslt/xsltlocale.h12
-rw-r--r--libxslt/xsltutils.c8
-rw-r--r--win32/configure.js6
12 files changed, 263 insertions, 191 deletions
diff --git a/ChangeLog b/ChangeLog
index d3236ea0..cbdaa498 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Fri Aug 1 10:16:48 CEST 2008 Daniel Veillard <veillard@redhat.com>
+
+ * libxslt/xsltconfig.h.in libxslt/xslt.c libxslt/extensions.c
+ libxslt/xsltlocale.c libxslt/preproc.c libxslt/xsltutils.c
+ libxslt/xsltlocale.h libxslt/win32config.h configure.in
+ config.h.in win32/configure.js: big patch from Roumen Petrov
+ finishing xsl:sort lang support with many portability issues
+ fixed and feedback from Nick Wellnhofer and Rob Richards
+
Fri Aug 1 07:54:02 CEST 2008 Daniel Veillard <veillard@redhat.com>
* libexslt/crypto.c: fix for CVE-2008-2935 libexslt RC4
@@ -39,7 +48,8 @@ Tue Jun 24 23:55:48 PST 2008 William Brack <wbrack@mmm.com.hk>
Fri Jun 13 10:58:52 CEST 2008 Daniel Veillard <daniel@veillard.com>
* libxslt/libxslt.h libexslt/libexslt.h libexslt/exslt.h: patch
- from Roumen Petrov fixing include path when compiling with MinGW
+ from Roumen Petrov fixing include path when compiling outside
+ source tree
Thu Jun 12 11:23:23 CEST 2008 Daniel Veillard <daniel@veillard.com>
diff --git a/config.h.in b/config.h.in
index 83448e39..7b8783da 100644
--- a/config.h.in
+++ b/config.h.in
@@ -42,6 +42,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
/* Define to 1 if you have the `localtime' function. */
#undef HAVE_LOCALTIME
diff --git a/configure.in b/configure.in
index 28fb1ffc..6439edc2 100644
--- a/configure.in
+++ b/configure.in
@@ -107,31 +107,48 @@ AC_STDC_HEADERS
AM_PROG_LIBTOOL
+AC_CHECK_HEADERS(sys/types.h sys/time.h stdlib.h unistd.h string.h)
+
dnl
dnl Detect supported locale
dnl
XSLT_LOCALE_XLOCALE=0
-XSLT_LOCALE_MSVCRT=0
+XSLT_LOCALE_WINAPI=0
-AC_CHECK_HEADERS([xlocale.h])
+AC_CHECK_HEADERS([locale.h xlocale.h])
if test $ac_cv_header_xlocale_h = yes; then
-AC_MSG_CHECKING([for working xlocale])
-AC_RUN_IFELSE(AC_LANG_PROGRAM([[
+dnl
+dnl Check for generic locale_t declaration
+dnl
+AC_MSG_CHECKING([if xlocale program link])
+AC_LINK_IFELSE(AC_LANG_PROGRAM([[
+#ifdef HAVE_LOCALE_H
#include <locale.h>
+#endif
+#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
+#endif
+#ifdef HAVE_STRING_H
#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
+#endif
+#ifdef __GLIBC__
+typedef __locale_t xsltLocale;
+#else
+typedef locale_t xsltLocale;
+#endif
#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 2
-#define locale_t __locale_t
#define newlocale __newlocale
#define freelocale __freelocale
#define strxfrm_l __strxfrm_l
#define LC_COLLATE_MASK (1 << LC_COLLATE)
#endif
]],[[
- locale_t locale;
+ xsltLocale locale;
const char *src[[2]] = { "\xc3\x84rger", "Zeppelin" };
char *dst[[2]];
size_t len, r;
@@ -152,24 +169,23 @@ AC_RUN_IFELSE(AC_LANG_PROGRAM([[
return(0);
]]),
[AC_MSG_RESULT(yes); XSLT_LOCALE_XLOCALE=1],
- [AC_MSG_RESULT(no)],
- [AC_MSG_WARN([cross compiling: assuming no])]
+ [AC_MSG_RESULT(no)]
)
else
- dnl defined in msvcrt
- AC_CHECK_FUNC(_create_locale,
- [XSLT_LOCALE_MSVCRT=1]
- )
+ case "$host" in
+ *-*-mingw*)
+ AC_MSG_NOTICE([using winapi locale])
+ XSLT_LOCALE_WINAPI=1;;
+ esac
fi
AC_SUBST(XSLT_LOCALE_XLOCALE)
-AC_SUBST(XSLT_LOCALE_MSVCRT)
+AC_SUBST(XSLT_LOCALE_WINAPI)
dnl
dnl Math detection
dnl
-AC_CHECK_HEADERS(sys/types.h sys/time.h stdlib.h unistd.h string.h)
AC_CHECK_HEADERS(ieeefp.h nan.h math.h fp_class.h float.h ansidecl.h)
AC_CHECK_HEADERS(sys/timeb.h time.h sys/stat.h sys/select.h stdarg.h)
AC_CHECK_FUNCS(stat _stat)
diff --git a/libxslt/extensions.c b/libxslt/extensions.c
index 2c1b239d..87eefb45 100644
--- a/libxslt/extensions.c
+++ b/libxslt/extensions.c
@@ -34,8 +34,10 @@
#ifdef _WIN32
#include <stdlib.h> /* for _MAX_PATH */
+#ifndef PATH_MAX
#define PATH_MAX _MAX_PATH
#endif
+#endif
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_EXTENSIONS
diff --git a/libxslt/preproc.c b/libxslt/preproc.c
index 42908384..9a5e9d69 100644
--- a/libxslt/preproc.c
+++ b/libxslt/preproc.c
@@ -391,7 +391,7 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
break;
case XSLT_FUNC_SORT: {
xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp;
- if (item->locale != NULL)
+ if (item->locale != (xsltLocale)0)
xsltFreeLocale(item->locale);
if (item->comp != NULL)
xmlXPathFreeCompExpr(item->comp);
@@ -489,7 +489,7 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
break;
}
#else
- if (comp->locale != NULL)
+ if (comp->locale != (xsltLocale)0)
xsltFreeLocale(comp->locale);
if (comp->comp != NULL)
xmlXPathFreeCompExpr(comp->comp);
@@ -736,7 +736,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
comp->locale = xsltNewLocale(comp->lang);
}
else {
- comp->locale = NULL;
+ comp->locale = (xsltLocale)0;
}
comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);
diff --git a/libxslt/win32config.h b/libxslt/win32config.h
index 169b03d1..00ba2a0e 100644
--- a/libxslt/win32config.h
+++ b/libxslt/win32config.h
@@ -95,5 +95,7 @@ static int isnan (double d) {
#define ATTRIBUTE_UNUSED
#endif
+#define _WINSOCKAPI_
+
#endif /* __LIBXSLT_WIN32_CONFIG__ */
diff --git a/libxslt/xslt.c b/libxslt/xslt.c
index 071658b4..f35ad237 100644
--- a/libxslt/xslt.c
+++ b/libxslt/xslt.c
@@ -83,6 +83,9 @@ const xmlChar *xsltXSLTAttrMarker = (const xmlChar *) "LRE XSLT Attr";
#endif
+#ifdef XSLT_LOCALE_WINAPI
+extern xmlRMutexPtr xsltLocaleMutex;
+#endif
/*
* Harmless but avoiding a problem when compiling against a
* libxml <= 2.3.11 without LIBXML_DEBUG_ENABLED
@@ -222,6 +225,9 @@ void
xsltInit (void) {
if (initialized == 0) {
initialized = 1;
+#ifdef XSLT_LOCALE_WINAPI
+ xsltLocaleMutex = xmlNewRMutex();
+#endif
xsltRegisterAllExtras();
}
}
diff --git a/libxslt/xsltconfig.h.in b/libxslt/xsltconfig.h.in
index e9a3c56c..b4cac6d3 100644
--- a/libxslt/xsltconfig.h.in
+++ b/libxslt/xsltconfig.h.in
@@ -130,9 +130,9 @@ extern "C" {
#ifndef XSLT_LOCALE_XLOCALE
#define XSLT_LOCALE_XLOCALE
#endif
-#elif @XSLT_LOCALE_MSVCRT@
-#ifndef XSLT_LOCALE_MSVCRT
-#define XSLT_LOCALE_MSVCRT
+#elif @XSLT_LOCALE_WINAPI@
+#ifndef XSLT_LOCALE_WINAPI
+#define XSLT_LOCALE_WINAPI
#endif
#endif
diff --git a/libxslt/xsltlocale.c b/libxslt/xsltlocale.c
index 0b76ec09..9c57805f 100644
--- a/libxslt/xsltlocale.c
+++ b/libxslt/xsltlocale.c
@@ -7,6 +7,7 @@
* ISO 639-1, ISO 3166-1
*
* Author: Nick Wellnhofer
+ * winapi port: Roumen Petrov
*/
#define IN_LIBXSLT
@@ -29,6 +30,42 @@
#define TOUPPER(c) (c & ~0x20)
#define TOLOWER(c) (c | 0x20)
+/*without terminating null character*/
+#define XSLTMAX_ISO639LANGLEN 8
+#define XSLTMAX_ISO3166CNTRYLEN 8
+ /* <lang>-<cntry> */
+#define XSLTMAX_LANGTAGLEN (XSLTMAX_ISO639LANGLEN+1+XSLTMAX_ISO3166CNTRYLEN)
+
+static const xmlChar* xsltDefaultRegion(const xmlChar *localeName);
+
+#ifdef XSLT_LOCALE_WINAPI
+xmlRMutexPtr xsltLocaleMutex = NULL;
+
+struct xsltRFC1766Info_s {
+ /*note typedef unsigned char xmlChar !*/
+ xmlChar tag[XSLTMAX_LANGTAGLEN+1];
+ /*note typedef LCID xsltLocale !*/
+ xsltLocale lcid;
+};
+typedef struct xsltRFC1766Info_s xsltRFC1766Info;
+
+static int xsltLocaleListSize = 0;
+static xsltRFC1766Info *xsltLocaleList = NULL;
+
+
+static xsltLocale
+xslt_locale_WINAPI(const xmlChar *languageTag) {
+ int k;
+ xsltRFC1766Info *p = xsltLocaleList;
+
+ for (k=0; k<xsltLocaleListSize; k++, p++)
+ if (xmlStrcmp(p->tag, languageTag) == 0) return p->lcid;
+ return((xsltLocale)0);
+}
+
+static void xsltEnumSupportedLocales(void);
+#endif
+
/**
* xsltNewLocale:
* @languageTag: RFC 3066 language tag
@@ -43,7 +80,7 @@ xsltLocale
xsltNewLocale(const xmlChar *languageTag) {
#ifdef XSLT_LOCALE_XLOCALE
xsltLocale locale;
- char localeName[23]; /* 8*lang + "-" + 8*region + ".utf8\0" */
+ char localeName[XSLTMAX_LANGTAGLEN+6]; /* 8*lang + "-" + 8*region + ".utf8\0" */
const xmlChar *p = languageTag;
const char *region = NULL;
char *q = localeName;
@@ -54,7 +91,7 @@ xsltNewLocale(const xmlChar *languageTag) {
if (languageTag == NULL)
return(NULL);
- for (i=0; i<8 && ISALPHA(*p); ++i)
+ for (i=0; i<XSLTMAX_ISO639LANGLEN && ISALPHA(*p); ++i)
*q++ = TOLOWER(*p++);
if (i == 0)
@@ -67,7 +104,7 @@ xsltNewLocale(const xmlChar *languageTag) {
if (*p++ != '-')
return(NULL);
- for (i=0; i<8 && ISALPHA(*p); ++i)
+ for (i=0; i<XSLTMAX_ISO3166CNTRYLEN && ISALPHA(*p); ++i)
*q++ = TOUPPER(*p++);
if (i == 0 || *p)
@@ -86,8 +123,70 @@ xsltNewLocale(const xmlChar *languageTag) {
if (llen != 2)
return(NULL);
- c = localeName[1];
+ region = xsltDefaultRegion(localeName);
+ if (region == NULL)
+ return(NULL);
+
+ *q++ = region[0];
+ *q++ = region[1];
+ memcpy(q, ".utf8", 6);
+ locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
+
+ return(locale);
+#endif
+
+#ifdef XSLT_LOCALE_WINAPI
+{
+ xsltLocale locale = (xsltLocale)0;
+ xmlChar localeName[XSLTMAX_LANGTAGLEN+1];
+ xmlChar *q = localeName;
+ const xmlChar *p = languageTag;
+ int i, llen;
+ const xmlChar *region = NULL;
+
+ if (languageTag == NULL) goto end;
+
+ xsltEnumSupportedLocales();
+
+ for (i=0; i<XSLTMAX_ISO639LANGLEN && ISALPHA(*p); ++i)
+ *q++ = TOLOWER(*p++);
+ if (i == 0) goto end;
+
+ llen = i;
+ *q++ = '-';
+ if (*p) { /*if country tag is given*/
+ if (*p++ != '-') goto end;
+
+ for (i=0; i<XSLTMAX_ISO3166CNTRYLEN && ISALPHA(*p); ++i)
+ *q++ = TOUPPER(*p++);
+ if (i == 0 || *p) goto end;
+
+ *q = '\0';
+ locale = xslt_locale_WINAPI(localeName);
+ if (locale != (xsltLocale)0) goto end;
+ }
+ /* Try to find most common country for language */
+ region = xsltDefaultRegion(localeName);
+ if (region == NULL) goto end;
+
+ strcpy(localeName + llen + 1, region);
+ locale = xslt_locale_WINAPI(localeName);
+end:
+ return(locale);
+}
+#endif
+
+#ifdef XSLT_LOCALE_NONE
+ return(NULL);
+#endif
+}
+
+static const xmlChar*
+xsltDefaultRegion(const xmlChar *localeName) {
+ xmlChar c;
+ const xmlChar *region = NULL;
+ c = localeName[1];
/* This is based on the locales from glibc 2.3.3 */
switch (localeName[0]) {
@@ -216,95 +315,7 @@ xsltNewLocale(const xmlChar *languageTag) {
else if (c == 'u') region = "ZA";
break;
}
-
- if (region == NULL)
- return(NULL);
-
- *q++ = region[0];
- *q++ = region[1];
- memcpy(q, ".utf8", 6);
- locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
-
- return(locale);
-#endif
-
-#ifdef XSLT_LOCALE_MSVCRT
- const char *localeName = NULL;
- int c;
-
- /* We only look at the language and ignore the region. I think Windows
- doesn't care about the region for LC_COLLATE anyway. */
-
- if (languageTag == NULL ||
- !languageTag[0] ||
- !languageTag[1] ||
- languageTag[2] && languageTag[2] != '-')
- return(NULL);
-
- c = TOLOWER(languageTag[1]);
-
- switch (TOLOWER(languageTag[0])) {
- case 'c':
- if (c == 's') localeName = "csy"; /* Czech */
- break;
- case 'd':
- if (c == 'a') localeName = "dan"; /* Danish */
- else if (c == 'e') localeName = "deu"; /* German */
- break;
- case 'e':
- if (c == 'l') localeName = "ell"; /* Greek */
- else if (c == 'n') localeName = "english";
- else if (c == 's') localeName = "esp"; /* Spanish */
- break;
- case 'f':
- if (c == 'i') localeName = "fin"; /* Finnish */
- else if (c == 'r') localeName = "fra"; /* French */
- break;
- case 'h':
- if (c == 'u') localeName = "hun"; /* Hungarian */
- break;
- case 'i':
- if (c == 's') localeName = "isl"; /* Icelandic */
- else if (c == 't') localeName = "ita"; /* Italian */
- break;
- case 'j':
- if (c == 'a') localeName = "jpn"; /* Japanese */
- break;
- case 'k':
- if (c == 'o') localeName = "kor"; /* Korean */
- break;
- case 'n':
- if (c == 'l') localeName = "nld"; /* Dutch */
- else if (c == 'o') localeName = "norwegian";
- break;
- case 'p':
- if (c == 'l') localeName = "plk"; /* Polish */
- else if (c == 't') localeName = "ptg"; /* Portuguese */
- break;
- case 'r':
- if (c == 'u') localeName = "rus"; /* Russian */
- break;
- case 's':
- if (c == 'k') localeName = "sky"; /* Slovak */
- else if (c == 'v') localeName = "sve"; /* Swedish */
- break;
- case 't':
- if (c == 'r') localeName = "trk"; /* Turkish */
- break;
- case 'z':
- if (c == 'h') localeName = "chinese";
- break;
- }
-
- if (localeName == NULL)
- return(NULL);
-
- return(_create_locale(LC_COLLATE, localeName));
-#endif
-
-#ifdef XSLT_LOCALE_NONE
- return(NULL);
-#endif
+ return(region);
}
/**
@@ -317,10 +328,6 @@ xsltFreeLocale(xsltLocale locale) {
#ifdef XSLT_LOCALE_XLOCALE
freelocale(locale);
#endif
-
-#ifdef XSLT_LOCALE_MSVCRT
- _free_locale(locale);
-#endif
}
/**
@@ -354,71 +361,26 @@ xsltStrxfrm(xsltLocale locale, const xmlChar *string)
r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, locale);
#endif
-#ifdef XSLT_LOCALE_MSVCRT
- wchar_t *wcs;
- wchar_t dummy;
- int wcslen;
- int i, j;
-
- /* convert UTF8 to Windows wide chars (UTF16) */
-
- wcslen = xmlUTF8Strlen(string);
- if (wcslen < 0) {
- xsltTransformError(NULL, NULL, NULL,
- "xsltStrxfrm : invalid UTF-8 string\n");
+#ifdef XSLT_LOCALE_WINAPI
+ xstrlen = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
+ if (xstrlen == 0) {
+ xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n");
return(NULL);
}
- wcs = (wchar_t *) xmlMalloc(sizeof(wchar_t) * (wcslen + 1));
- if (wcs == NULL) {
- xsltTransformError(NULL, NULL, NULL,
- "xsltStrxfrm : out of memory error\n");
- return(NULL);
- }
-
- for (i=0, j=0; i<wcslen; ++i) {
- int len = 4; /* not really, but string is already checked */
- int c = xmlGetUTF8Char(string, &len);
-#if 0
- if (c < 0) {
- xsltTransformError(NULL, NULL, NULL,
- "xsltStrxfrm : invalid UTF-8 string\n");
- xmlFree(wcs);
- return(NULL);
- }
-#endif
-
- if (c == (wchar_t)c) {
- wcs[j] = (wchar_t)c;
- ++j;
- }
-
- string += len;
- }
-
- wcs[j] = 0;
-
- /* _wcsxfrm_l needs a dummy strDest because it always writes at least one
- terminating zero wchar */
- xstrlen = _wcsxfrm_l(&dummy, wcs, 0, locale);
- if (xstrlen == INT_MAX) {
- xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n");
- xmlFree(wcs);
+ xstr = (xsltLocaleChar*) xmlMalloc(xstrlen * sizeof(xsltLocaleChar));
+ if (xstr == NULL) {
+ xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n");
return(NULL);
}
- ++xstrlen;
- xstr = (wchar_t *) xmlMalloc(sizeof(wchar_t) * xstrlen);
- if (xstr == NULL) {
- xsltTransformError(NULL, NULL, NULL,
- "xsltStrxfrm : out of memory error\n");
- xmlFree(wcs);
- return(NULL);
+ r = MultiByteToWideChar(CP_UTF8, 0, string, -1, xstr, xstrlen);
+ if (r == 0) {
+ xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar failed\n");
+ xmlFree(xstr);
+ return(NULL);
}
+ return(xstr);
+#endif /* XSLT_LOCALE_WINAPI */
- r = _wcsxfrm_l(xstr, wcs, xstrlen, locale);
-
- xmlFree(wcs);
-#endif /* XSLT_LOCALE_MSVCRT */
-
if (r >= xstrlen) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n");
xmlFree(xstr);
@@ -431,6 +393,7 @@ xsltStrxfrm(xsltLocale locale, const xmlChar *string)
/**
* xsltLocaleStrcmp:
+ * @locale: a locale identifier
* @str1: a string transformed with xsltStrxfrm
* @str2: a string transformed with xsltStrxfrm
*
@@ -441,13 +404,79 @@ xsltStrxfrm(xsltLocale locale, const xmlChar *string)
* 0 if str1 and str2 are equal wrt sorting
*/
int
-xsltLocaleStrcmp(const xsltLocaleChar *str1, const xsltLocaleChar *str2) {
-#ifdef XSLT_LOCALE_MSVCRT
+xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2) {
+ (void)locale;
+#ifdef XSLT_LOCALE_WINAPI
+{
+ int ret;
if (str1 == str2) return(0);
if (str1 == NULL) return(-1);
if (str2 == NULL) return(1);
- return(wcscmp(str1, str2));
+ ret = CompareStringW(locale, 0, str1, -1, str2, -1);
+ if (ret == 0) {
+ xsltTransformError(NULL, NULL, NULL, "xsltLocaleStrcmp : CompareStringW fail\n");
+ return(0);
+ }
+ return(ret - 2);
+}
#else
return(xmlStrcmp(str1, str2));
#endif
}
+
+#ifdef XSLT_LOCALE_WINAPI
+BOOL CALLBACK
+xsltCountSupportedLocales(LPSTR lcid) {
+ (void) lcid;
+ ++xsltLocaleListSize;
+ return(TRUE);
+}
+
+BOOL CALLBACK
+xsltIterateSupportedLocales(LPSTR lcid) {
+ static int count = 0;
+ xmlChar iso639lang [XSLTMAX_ISO639LANGLEN +1];
+ xmlChar iso3136ctry[XSLTMAX_ISO3166CNTRYLEN+1];
+ int k, l;
+ xsltRFC1766Info *p = xsltLocaleList + count;
+
+ k = sscanf(lcid, "%lx", (long*)&p->lcid);
+ if (k < 1) goto end;
+ /*don't count terminating null character*/
+ k = GetLocaleInfoA(p->lcid, LOCALE_SISO639LANGNAME , iso639lang , sizeof(iso639lang ));
+ if (--k < 1) goto end;
+ l = GetLocaleInfoA(p->lcid, LOCALE_SISO3166CTRYNAME, iso3136ctry, sizeof(iso3136ctry));
+ if (--l < 1) goto end;
+
+ { /*fill results*/
+ xmlChar *q = p->tag;
+ memcpy(q, iso639lang, k);
+ q += k;
+ *q++ = '-';
+ memcpy(q, iso3136ctry, l);
+ q += l;
+ *q = '\0';
+ }
+ ++count;
+end:
+ return((count < xsltLocaleListSize) ? TRUE : FALSE);
+}
+
+
+static void
+xsltEnumSupportedLocales(void) {
+ xmlRMutexLock(xsltLocaleMutex);
+ if (xsltLocaleListSize <= 0) {
+ size_t len;
+
+ EnumSystemLocalesA(xsltCountSupportedLocales, LCID_SUPPORTED);
+
+ len = xsltLocaleListSize * sizeof(xsltRFC1766Info);
+ xsltLocaleList = xmlMalloc(len);
+ memset(xsltLocaleList, 0, len);
+ EnumSystemLocalesA(xsltIterateSupportedLocales, LCID_SUPPORTED);
+ }
+ xmlRMutexUnlock(xsltLocaleMutex);
+}
+
+#endif /*def XSLT_LOCALE_WINAPI*/
diff --git a/libxslt/xsltlocale.h b/libxslt/xsltlocale.h
index c700df4e..2f20d630 100644
--- a/libxslt/xsltlocale.h
+++ b/libxslt/xsltlocale.h
@@ -18,18 +18,20 @@
#include <locale.h>
#include <xlocale.h>
-#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 2
+#ifdef __GLIBC__
+/*locale_t is defined only if _GNU_SOURCE is defined*/
typedef __locale_t xsltLocale;
#else
typedef locale_t xsltLocale;
#endif
typedef xmlChar xsltLocaleChar;
-#elif defined(XSLT_LOCALE_MSVCRT)
+#elif defined(XSLT_LOCALE_WINAPI)
-#include <locale.h>
+#include <windows.h>
+#include <winnls.h>
-typedef _locale_t xsltLocale;
+typedef LCID xsltLocale;
typedef wchar_t xsltLocaleChar;
#else
@@ -46,6 +48,6 @@ typedef xmlChar xsltLocaleChar;
xsltLocale xsltNewLocale(const xmlChar *langName);
void xsltFreeLocale(xsltLocale locale);
xsltLocaleChar *xsltStrxfrm(xsltLocale locale, const xmlChar *string);
-int xsltLocaleStrcmp(const xsltLocaleChar *str1, const xsltLocaleChar *str2);
+int xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2);
#endif /* __XML_XSLTLOCALE_H__ */
diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
index 4650215b..9565e152 100644
--- a/libxslt/xsltutils.c
+++ b/libxslt/xsltutils.c
@@ -1039,7 +1039,7 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {
}
} else {
if (res->type == XPATH_STRING) {
- if (comp->locale != NULL) {
+ if (comp->locale != (xsltLocale)0) {
xmlChar *str = res->stringval;
res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str);
xmlFree(str);
@@ -1197,8 +1197,9 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
results[j + incr]->floatval)
tst = 1;
else tst = -1;
- } else if(comp->locale != NULL) {
+ } else if(comp->locale != (xsltLocale)0) {
tst = xsltLocaleStrcmp(
+ comp->locale,
(xsltLocaleChar *) results[j]->stringval,
(xsltLocaleChar *) results[j + incr]->stringval);
} else {
@@ -1255,8 +1256,9 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
res[j + incr]->floatval)
tst = 1;
else tst = -1;
- } else if(comp->locale != NULL) {
+ } else if(comp->locale != (xsltLocale)0) {
tst = xsltLocaleStrcmp(
+ comp->locale,
(xsltLocaleChar *) res[j]->stringval,
(xsltLocaleChar *) res[j + incr]->stringval);
} else {
diff --git a/win32/configure.js b/win32/configure.js
index 4feb4b27..7f2f8548 100644
--- a/win32/configure.js
+++ b/win32/configure.js
@@ -107,7 +107,7 @@ function usage()
txt += " zlib: Use zlib library (" + (withZlib? "yes" : "no") + ")\n";
txt += " crypto: Enable Crypto support (" + (withCrypto? "yes" : "no") + ")\n";
txt += " modules: Enable Module support (" + (withModules? "yes" : "no") + ")\n";
- txt += " locale: Enable Locale support, requires msvcr80.dll (" + (withLocale? "yes" : "no") + ")\n";
+ txt += " locale: Enable Locale support, requires unicode OS support (" + (withLocale? "yes" : "no") + ")\n";
txt += "\nWin32 build options, default value given in parentheses:\n\n";
txt += " compiler: Compiler to be used [msvc|mingw] (" + compiler + ")\n";
txt += " cruntime: C-runtime compiler option (only msvc) (" + cruntime + ")\n";
@@ -244,8 +244,8 @@ function configureXslt()
of.WriteLine(s.replace(/\@WITH_MODULES\@/, withModules? "1" : "0"));
} else if (s.search(/\@XSLT_LOCALE_XLOCALE\@/) != -1) {
of.WriteLine(s.replace(/\@XSLT_LOCALE_XLOCALE\@/, "0"));
- } else if (s.search(/\@XSLT_LOCALE_MSVCRT\@/) != -1) {
- of.WriteLine(s.replace(/\@XSLT_LOCALE_MSVCRT\@/, withLocale? "1" : "0"));
+ } else if (s.search(/\@XSLT_LOCALE_WINAPI\@/) != -1) {
+ of.WriteLine(s.replace(/\@XSLT_LOCALE_WINAPI\@/, withLocale? "1" : "0"));
} else if (s.search(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/) != -1) {
of.WriteLine(s.replace(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/, "NULL"));
} else