1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-07-29 15:41:13 +03:00

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
This commit is contained in:
Daniel Veillard
2008-08-01 08:27:18 +00:00
parent a85673c19d
commit 79ab294f6f
12 changed files with 264 additions and 192 deletions

View File

@ -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> Fri Aug 1 07:54:02 CEST 2008 Daniel Veillard <veillard@redhat.com>
* libexslt/crypto.c: fix for CVE-2008-2935 libexslt RC4 * 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> Fri Jun 13 10:58:52 CEST 2008 Daniel Veillard <daniel@veillard.com>
* libxslt/libxslt.h libexslt/libexslt.h libexslt/exslt.h: patch * 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> Thu Jun 12 11:23:23 CEST 2008 Daniel Veillard <daniel@veillard.com>

View File

@ -42,6 +42,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H #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. */ /* Define to 1 if you have the `localtime' function. */
#undef HAVE_LOCALTIME #undef HAVE_LOCALTIME

View File

@ -107,31 +107,48 @@ AC_STDC_HEADERS
AM_PROG_LIBTOOL AM_PROG_LIBTOOL
AC_CHECK_HEADERS(sys/types.h sys/time.h stdlib.h unistd.h string.h)
dnl dnl
dnl Detect supported locale dnl Detect supported locale
dnl dnl
XSLT_LOCALE_XLOCALE=0 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 if test $ac_cv_header_xlocale_h = yes; then
AC_MSG_CHECKING([for working xlocale]) dnl
AC_RUN_IFELSE(AC_LANG_PROGRAM([[ 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> #include <locale.h>
#endif
#ifdef HAVE_XLOCALE_H
#include <xlocale.h> #include <xlocale.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h> #include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <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 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 2
#define locale_t __locale_t
#define newlocale __newlocale #define newlocale __newlocale
#define freelocale __freelocale #define freelocale __freelocale
#define strxfrm_l __strxfrm_l #define strxfrm_l __strxfrm_l
#define LC_COLLATE_MASK (1 << LC_COLLATE) #define LC_COLLATE_MASK (1 << LC_COLLATE)
#endif #endif
]],[[ ]],[[
locale_t locale; xsltLocale locale;
const char *src[[2]] = { "\xc3\x84rger", "Zeppelin" }; const char *src[[2]] = { "\xc3\x84rger", "Zeppelin" };
char *dst[[2]]; char *dst[[2]];
size_t len, r; size_t len, r;
@ -152,24 +169,23 @@ AC_RUN_IFELSE(AC_LANG_PROGRAM([[
return(0); return(0);
]]), ]]),
[AC_MSG_RESULT(yes); XSLT_LOCALE_XLOCALE=1], [AC_MSG_RESULT(yes); XSLT_LOCALE_XLOCALE=1],
[AC_MSG_RESULT(no)], [AC_MSG_RESULT(no)]
[AC_MSG_WARN([cross compiling: assuming no])]
) )
else else
dnl defined in msvcrt case "$host" in
AC_CHECK_FUNC(_create_locale, *-*-mingw*)
[XSLT_LOCALE_MSVCRT=1] AC_MSG_NOTICE([using winapi locale])
) XSLT_LOCALE_WINAPI=1;;
esac
fi fi
AC_SUBST(XSLT_LOCALE_XLOCALE) AC_SUBST(XSLT_LOCALE_XLOCALE)
AC_SUBST(XSLT_LOCALE_MSVCRT) AC_SUBST(XSLT_LOCALE_WINAPI)
dnl dnl
dnl Math detection dnl Math detection
dnl 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(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_HEADERS(sys/timeb.h time.h sys/stat.h sys/select.h stdarg.h)
AC_CHECK_FUNCS(stat _stat) AC_CHECK_FUNCS(stat _stat)

View File

@ -34,8 +34,10 @@
#ifdef _WIN32 #ifdef _WIN32
#include <stdlib.h> /* for _MAX_PATH */ #include <stdlib.h> /* for _MAX_PATH */
#ifndef PATH_MAX
#define PATH_MAX _MAX_PATH #define PATH_MAX _MAX_PATH
#endif #endif
#endif
#ifdef WITH_XSLT_DEBUG #ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_EXTENSIONS #define WITH_XSLT_DEBUG_EXTENSIONS

View File

@ -391,7 +391,7 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
break; break;
case XSLT_FUNC_SORT: { case XSLT_FUNC_SORT: {
xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp; xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp;
if (item->locale != NULL) if (item->locale != (xsltLocale)0)
xsltFreeLocale(item->locale); xsltFreeLocale(item->locale);
if (item->comp != NULL) if (item->comp != NULL)
xmlXPathFreeCompExpr(item->comp); xmlXPathFreeCompExpr(item->comp);
@ -489,7 +489,7 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
break; break;
} }
#else #else
if (comp->locale != NULL) if (comp->locale != (xsltLocale)0)
xsltFreeLocale(comp->locale); xsltFreeLocale(comp->locale);
if (comp->comp != NULL) if (comp->comp != NULL)
xmlXPathFreeCompExpr(comp->comp); xmlXPathFreeCompExpr(comp->comp);
@ -736,7 +736,7 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
comp->locale = xsltNewLocale(comp->lang); comp->locale = xsltNewLocale(comp->lang);
} }
else { else {
comp->locale = NULL; comp->locale = (xsltLocale)0;
} }
comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE); comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);

View File

@ -95,5 +95,7 @@ static int isnan (double d) {
#define ATTRIBUTE_UNUSED #define ATTRIBUTE_UNUSED
#endif #endif
#define _WINSOCKAPI_
#endif /* __LIBXSLT_WIN32_CONFIG__ */ #endif /* __LIBXSLT_WIN32_CONFIG__ */

View File

@ -83,6 +83,9 @@ const xmlChar *xsltXSLTAttrMarker = (const xmlChar *) "LRE XSLT Attr";
#endif #endif
#ifdef XSLT_LOCALE_WINAPI
extern xmlRMutexPtr xsltLocaleMutex;
#endif
/* /*
* Harmless but avoiding a problem when compiling against a * Harmless but avoiding a problem when compiling against a
* libxml <= 2.3.11 without LIBXML_DEBUG_ENABLED * libxml <= 2.3.11 without LIBXML_DEBUG_ENABLED
@ -222,6 +225,9 @@ void
xsltInit (void) { xsltInit (void) {
if (initialized == 0) { if (initialized == 0) {
initialized = 1; initialized = 1;
#ifdef XSLT_LOCALE_WINAPI
xsltLocaleMutex = xmlNewRMutex();
#endif
xsltRegisterAllExtras(); xsltRegisterAllExtras();
} }
} }

View File

@ -130,9 +130,9 @@ extern "C" {
#ifndef XSLT_LOCALE_XLOCALE #ifndef XSLT_LOCALE_XLOCALE
#define XSLT_LOCALE_XLOCALE #define XSLT_LOCALE_XLOCALE
#endif #endif
#elif @XSLT_LOCALE_MSVCRT@ #elif @XSLT_LOCALE_WINAPI@
#ifndef XSLT_LOCALE_MSVCRT #ifndef XSLT_LOCALE_WINAPI
#define XSLT_LOCALE_MSVCRT #define XSLT_LOCALE_WINAPI
#endif #endif
#endif #endif

View File

@ -7,6 +7,7 @@
* ISO 639-1, ISO 3166-1 * ISO 639-1, ISO 3166-1
* *
* Author: Nick Wellnhofer * Author: Nick Wellnhofer
* winapi port: Roumen Petrov
*/ */
#define IN_LIBXSLT #define IN_LIBXSLT
@ -29,6 +30,42 @@
#define TOUPPER(c) (c & ~0x20) #define TOUPPER(c) (c & ~0x20)
#define TOLOWER(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: * xsltNewLocale:
* @languageTag: RFC 3066 language tag * @languageTag: RFC 3066 language tag
@ -43,7 +80,7 @@ xsltLocale
xsltNewLocale(const xmlChar *languageTag) { xsltNewLocale(const xmlChar *languageTag) {
#ifdef XSLT_LOCALE_XLOCALE #ifdef XSLT_LOCALE_XLOCALE
xsltLocale locale; 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 xmlChar *p = languageTag;
const char *region = NULL; const char *region = NULL;
char *q = localeName; char *q = localeName;
@ -54,7 +91,7 @@ xsltNewLocale(const xmlChar *languageTag) {
if (languageTag == NULL) if (languageTag == NULL)
return(NULL); return(NULL);
for (i=0; i<8 && ISALPHA(*p); ++i) for (i=0; i<XSLTMAX_ISO639LANGLEN && ISALPHA(*p); ++i)
*q++ = TOLOWER(*p++); *q++ = TOLOWER(*p++);
if (i == 0) if (i == 0)
@ -67,7 +104,7 @@ xsltNewLocale(const xmlChar *languageTag) {
if (*p++ != '-') if (*p++ != '-')
return(NULL); return(NULL);
for (i=0; i<8 && ISALPHA(*p); ++i) for (i=0; i<XSLTMAX_ISO3166CNTRYLEN && ISALPHA(*p); ++i)
*q++ = TOUPPER(*p++); *q++ = TOUPPER(*p++);
if (i == 0 || *p) if (i == 0 || *p)
@ -86,8 +123,70 @@ xsltNewLocale(const xmlChar *languageTag) {
if (llen != 2) if (llen != 2)
return(NULL); 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 */ /* This is based on the locales from glibc 2.3.3 */
switch (localeName[0]) { switch (localeName[0]) {
@ -216,95 +315,7 @@ xsltNewLocale(const xmlChar *languageTag) {
else if (c == 'u') region = "ZA"; else if (c == 'u') region = "ZA";
break; break;
} }
return(region);
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
} }
/** /**
@ -317,10 +328,6 @@ xsltFreeLocale(xsltLocale locale) {
#ifdef XSLT_LOCALE_XLOCALE #ifdef XSLT_LOCALE_XLOCALE
freelocale(locale); freelocale(locale);
#endif #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); r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, locale);
#endif #endif
#ifdef XSLT_LOCALE_MSVCRT #ifdef XSLT_LOCALE_WINAPI
wchar_t *wcs; xstrlen = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
wchar_t dummy; if (xstrlen == 0) {
int wcslen; xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n");
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");
return(NULL); return(NULL);
} }
wcs = (wchar_t *) xmlMalloc(sizeof(wchar_t) * (wcslen + 1)); xstr = (xsltLocaleChar*) xmlMalloc(xstrlen * sizeof(xsltLocaleChar));
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);
return(NULL);
}
++xstrlen;
xstr = (wchar_t *) xmlMalloc(sizeof(wchar_t) * xstrlen);
if (xstr == NULL) { if (xstr == NULL) {
xsltTransformError(NULL, NULL, NULL, xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n");
"xsltStrxfrm : out of memory error\n"); return(NULL);
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) { if (r >= xstrlen) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n"); xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n");
xmlFree(xstr); xmlFree(xstr);
@ -431,6 +393,7 @@ xsltStrxfrm(xsltLocale locale, const xmlChar *string)
/** /**
* xsltLocaleStrcmp: * xsltLocaleStrcmp:
* @locale: a locale identifier
* @str1: a string transformed with xsltStrxfrm * @str1: a string transformed with xsltStrxfrm
* @str2: 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 * 0 if str1 and str2 are equal wrt sorting
*/ */
int int
xsltLocaleStrcmp(const xsltLocaleChar *str1, const xsltLocaleChar *str2) { xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2) {
#ifdef XSLT_LOCALE_MSVCRT (void)locale;
#ifdef XSLT_LOCALE_WINAPI
{
int ret;
if (str1 == str2) return(0); if (str1 == str2) return(0);
if (str1 == NULL) return(-1); if (str1 == NULL) return(-1);
if (str2 == 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 #else
return(xmlStrcmp(str1, str2)); return(xmlStrcmp(str1, str2));
#endif #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*/

View File

@ -18,18 +18,20 @@
#include <locale.h> #include <locale.h>
#include <xlocale.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; typedef __locale_t xsltLocale;
#else #else
typedef locale_t xsltLocale; typedef locale_t xsltLocale;
#endif #endif
typedef xmlChar xsltLocaleChar; 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; typedef wchar_t xsltLocaleChar;
#else #else
@ -46,6 +48,6 @@ typedef xmlChar xsltLocaleChar;
xsltLocale xsltNewLocale(const xmlChar *langName); xsltLocale xsltNewLocale(const xmlChar *langName);
void xsltFreeLocale(xsltLocale locale); void xsltFreeLocale(xsltLocale locale);
xsltLocaleChar *xsltStrxfrm(xsltLocale locale, const xmlChar *string); 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__ */ #endif /* __XML_XSLTLOCALE_H__ */

View File

@ -1039,7 +1039,7 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {
} }
} else { } else {
if (res->type == XPATH_STRING) { if (res->type == XPATH_STRING) {
if (comp->locale != NULL) { if (comp->locale != (xsltLocale)0) {
xmlChar *str = res->stringval; xmlChar *str = res->stringval;
res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str); res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str);
xmlFree(str); xmlFree(str);
@ -1197,8 +1197,9 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
results[j + incr]->floatval) results[j + incr]->floatval)
tst = 1; tst = 1;
else tst = -1; else tst = -1;
} else if(comp->locale != NULL) { } else if(comp->locale != (xsltLocale)0) {
tst = xsltLocaleStrcmp( tst = xsltLocaleStrcmp(
comp->locale,
(xsltLocaleChar *) results[j]->stringval, (xsltLocaleChar *) results[j]->stringval,
(xsltLocaleChar *) results[j + incr]->stringval); (xsltLocaleChar *) results[j + incr]->stringval);
} else { } else {
@ -1255,8 +1256,9 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
res[j + incr]->floatval) res[j + incr]->floatval)
tst = 1; tst = 1;
else tst = -1; else tst = -1;
} else if(comp->locale != NULL) { } else if(comp->locale != (xsltLocale)0) {
tst = xsltLocaleStrcmp( tst = xsltLocaleStrcmp(
comp->locale,
(xsltLocaleChar *) res[j]->stringval, (xsltLocaleChar *) res[j]->stringval,
(xsltLocaleChar *) res[j + incr]->stringval); (xsltLocaleChar *) res[j + incr]->stringval);
} else { } else {

View File

@ -107,7 +107,7 @@ function usage()
txt += " zlib: Use zlib library (" + (withZlib? "yes" : "no") + ")\n"; txt += " zlib: Use zlib library (" + (withZlib? "yes" : "no") + ")\n";
txt += " crypto: Enable Crypto support (" + (withCrypto? "yes" : "no") + ")\n"; txt += " crypto: Enable Crypto support (" + (withCrypto? "yes" : "no") + ")\n";
txt += " modules: Enable Module support (" + (withModules? "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 += "\nWin32 build options, default value given in parentheses:\n\n";
txt += " compiler: Compiler to be used [msvc|mingw] (" + compiler + ")\n"; txt += " compiler: Compiler to be used [msvc|mingw] (" + compiler + ")\n";
txt += " cruntime: C-runtime compiler option (only msvc) (" + cruntime + ")\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")); of.WriteLine(s.replace(/\@WITH_MODULES\@/, withModules? "1" : "0"));
} else if (s.search(/\@XSLT_LOCALE_XLOCALE\@/) != -1) { } else if (s.search(/\@XSLT_LOCALE_XLOCALE\@/) != -1) {
of.WriteLine(s.replace(/\@XSLT_LOCALE_XLOCALE\@/, "0")); of.WriteLine(s.replace(/\@XSLT_LOCALE_XLOCALE\@/, "0"));
} else if (s.search(/\@XSLT_LOCALE_MSVCRT\@/) != -1) { } else if (s.search(/\@XSLT_LOCALE_WINAPI\@/) != -1) {
of.WriteLine(s.replace(/\@XSLT_LOCALE_MSVCRT\@/, withLocale? "1" : "0")); of.WriteLine(s.replace(/\@XSLT_LOCALE_WINAPI\@/, withLocale? "1" : "0"));
} else if (s.search(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/) != -1) { } else if (s.search(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/) != -1) {
of.WriteLine(s.replace(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/, "NULL")); of.WriteLine(s.replace(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/, "NULL"));
} else } else