From 1a8e9f9ec06d6fa373c9d84eb98b268d9e1e446f Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Tue, 3 Jun 2008 16:40:54 +0000 Subject: [PATCH] patch from Nick Wellnhofer adding xsl:sort lang support using the locale * configure.in libxslt/extra.c libxslt/Makefile.am libxslt/preproc.c libxslt/xsltInternals.h libxslt/xsltlocale.c libxslt/xsltlocale.h libxslt/xsltutils.c win32/Makefile.mingw win32/Makefile.msvc: patch from Nick Wellnhofer adding xsl:sort lang support using the locale support from the C library. Daniel svn path=/trunk/; revision=1476 --- ChangeLog | 8 ++++++++ config.h.in | 8 ++++++++ configure.in | 43 +++++++++++++++++++++++++++++++++++++++++++ libxslt/Makefile.am | 4 +++- libxslt/extra.c | 1 - libxslt/preproc.c | 10 ++++++++++ libxslt/xsltInternals.h | 3 +++ libxslt/xsltutils.c | 14 ++++++++++++++ win32/Makefile.mingw | 2 ++ win32/Makefile.msvc | 3 +++ 10 files changed, 94 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ecddcaa..0573b46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Jun 3 18:26:26 CEST 2008 Daniel Veillard + + * configure.in libxslt/extra.c libxslt/Makefile.am libxslt/preproc.c + libxslt/xsltInternals.h libxslt/xsltlocale.c libxslt/xsltlocale.h + libxslt/xsltutils.c win32/Makefile.mingw win32/Makefile.msvc: patch + from Nick Wellnhofer adding xsl:sort lang support using the locale + support from the C library. + Tue Jun 3 18:14:55 CEST 2008 Daniel Veillard * libxslt/extensions.h: as Ralf Junker pointed out diff --git a/config.h.in b/config.h.in index 1b61d2b..1eebe19 100644 --- a/config.h.in +++ b/config.h.in @@ -123,6 +123,9 @@ /* Define to 1 if you have the `vsprintf' function. */ #undef HAVE_VSPRINTF +/* Have working xlocale.h */ +#undef HAVE_XLOCALE_H + /* Define to 1 if you have the `_stat' function. */ #undef HAVE__STAT @@ -150,6 +153,11 @@ /* Version number of package */ #undef VERSION +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif + /* Using the Win32 Socket implementation */ #undef _WINSOCKAPI_ diff --git a/configure.in b/configure.in index a7edf2b..7ad6b89 100644 --- a/configure.in +++ b/configure.in @@ -3,6 +3,7 @@ AC_PREREQ(2.2) AC_INIT(libxslt/xslt.c) AM_CONFIG_HEADER(config.h) AC_CANONICAL_HOST +AC_GNU_SOURCE dnl dnl libxslt is the main part of the package @@ -105,6 +106,48 @@ AC_PATH_PROG(TAR, tar, /bin/tar) AC_STDC_HEADERS AM_PROG_LIBTOOL +AC_MSG_CHECKING([for working xlocale.h]) +AC_TRY_RUN( +[ +#include +#include +#include +#include + +#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 + +int main() +{ + locale_t locale; + const char *src[2] = { "\xc3\x84rger", "Zeppelin" }; + char *dst[2]; + size_t len, r; + int i; + + locale = newlocale(LC_COLLATE_MASK, "en_US.utf8", NULL); + if (locale == NULL) exit(1); + for (i=0; i<2; ++i) { + len = strxfrm_l(NULL, src[i], 0, locale) + 1; + dst[i] = malloc(len); + if(dst[i] == NULL) exit(1); + r = strxfrm_l(dst[i], src[i], len, locale); + if(r >= len) exit(1); + } + if (strcmp(dst[0], dst[1]) >= 0) exit(1); + + exit(0); +} +], + [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_XLOCALE_H, 1, [Have working xlocale.h])], + [AC_MSG_RESULT(no)] +) + dnl dnl Math detection dnl diff --git a/libxslt/Makefile.am b/libxslt/Makefile.am index d5aff94..a93b45b 100644 --- a/libxslt/Makefile.am +++ b/libxslt/Makefile.am @@ -24,11 +24,13 @@ xsltinc_HEADERS = \ security.h \ xsltInternals.h \ xsltconfig.h \ - xsltexports.h + xsltexports.h \ + xsltlocale.h libxslt_la_SOURCES = \ attrvt.c \ xslt.c \ + xsltlocale.c \ xsltutils.c \ pattern.c \ templates.c \ diff --git a/libxslt/extra.c b/libxslt/extra.c index 51b6c73..3a0f547 100644 --- a/libxslt/extra.c +++ b/libxslt/extra.c @@ -15,7 +15,6 @@ #include #ifdef HAVE_TIME_H -#define __USE_XOPEN #include #endif #ifdef HAVE_STDLIB_H diff --git a/libxslt/preproc.c b/libxslt/preproc.c index 2842370..4290838 100644 --- a/libxslt/preproc.c +++ b/libxslt/preproc.c @@ -391,6 +391,8 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) { break; case XSLT_FUNC_SORT: { xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp; + if (item->locale != NULL) + xsltFreeLocale(item->locale); if (item->comp != NULL) xmlXPathFreeCompExpr(item->comp); } @@ -487,6 +489,8 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) { break; } #else + if (comp->locale != NULL) + xsltFreeLocale(comp->locale); if (comp->comp != NULL) xmlXPathFreeCompExpr(comp->comp); if (comp->nsList != NULL) @@ -728,6 +732,12 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { comp->lang = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"lang", NULL, &comp->has_lang); + if (comp->lang != NULL) { + comp->locale = xsltNewLocale(comp->lang); + } + else { + comp->locale = NULL; + } comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE); if (comp->select == NULL) { diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index f176264..bba2476 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -21,6 +21,7 @@ #include #include #include "xsltexports.h" +#include "xsltlocale.h" #include "numbersInternals.h" #ifdef __cplusplus @@ -1045,6 +1046,7 @@ struct _xsltStyleItemSort { int descending; /* sort */ const xmlChar *lang; /* sort */ int has_lang; /* sort */ + xsltLocale locale; /* sort */ const xmlChar *case_order; /* sort */ int lower_first; /* sort */ @@ -1381,6 +1383,7 @@ struct _xsltStylePreComp { int descending; /* sort */ const xmlChar *lang; /* sort */ int has_lang; /* sort */ + xsltLocale locale; /* sort */ const xmlChar *case_order; /* sort */ int lower_first; /* sort */ diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c index 603b22e..4650215 100644 --- a/libxslt/xsltutils.c +++ b/libxslt/xsltutils.c @@ -1039,6 +1039,12 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) { } } else { if (res->type == XPATH_STRING) { + if (comp->locale != NULL) { + xmlChar *str = res->stringval; + res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str); + xmlFree(str); + } + results[i] = res; } else { #ifdef WITH_XSLT_DEBUG_PROCESS @@ -1191,6 +1197,10 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, results[j + incr]->floatval) tst = 1; else tst = -1; + } else if(comp->locale != NULL) { + tst = xsltLocaleStrcmp( + (xsltLocaleChar *) results[j]->stringval, + (xsltLocaleChar *) results[j + incr]->stringval); } else { tst = xmlStrcmp(results[j]->stringval, results[j + incr]->stringval); @@ -1245,6 +1255,10 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, res[j + incr]->floatval) tst = 1; else tst = -1; + } else if(comp->locale != NULL) { + tst = xsltLocaleStrcmp( + (xsltLocaleChar *) res[j]->stringval, + (xsltLocaleChar *) res[j + incr]->stringval); } else { tst = xmlStrcmp(res[j]->stringval, res[j + incr]->stringval); diff --git a/win32/Makefile.mingw b/win32/Makefile.mingw index 0b2249d..946ffa3 100644 --- a/win32/Makefile.mingw +++ b/win32/Makefile.mingw @@ -87,6 +87,7 @@ XSLT_OBJS = $(XSLT_INTDIR)/attributes.o\ $(XSLT_INTDIR)/transform.o\ $(XSLT_INTDIR)/variables.o\ $(XSLT_INTDIR)/xslt.o\ + $(XSLT_INTDIR)/xsltlocale.o\ $(XSLT_INTDIR)/xsltutils.o XSLT_SRCS = $(subst .o,.c,$(subst $(XSLT_INTDIR),$(XSLT_SRCDIR),$(XSLT_OBJS))) @@ -107,6 +108,7 @@ XSLT_OBJS_A = $(XSLT_INTDIR_A)/attributes.o\ $(XSLT_INTDIR_A)/transform.o\ $(XSLT_INTDIR_A)/variables.o\ $(XSLT_INTDIR_A)/xslt.o\ + $(XSLT_INTDIR_A)/xsltlocale.o\ $(XSLT_INTDIR_A)/xsltutils.o # Libexslt object files. diff --git a/win32/Makefile.msvc b/win32/Makefile.msvc index b5810de..54e8e23 100644 --- a/win32/Makefile.msvc +++ b/win32/Makefile.msvc @@ -53,6 +53,7 @@ CPPFLAGS = /nologo CC = cl.exe CFLAGS = /nologo /D "WIN32" /D "_WINDOWS" /D "_MBCS" /W3 $(CRUNTIME) /D "_REENTRANT" CFLAGS = $(CFLAGS) /I$(BASEDIR) /I$(XSLT_SRCDIR) /I$(INCPREFIX) +CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE # The linker and its options. LD = link.exe @@ -90,6 +91,7 @@ XSLT_OBJS = $(XSLT_INTDIR)\attributes.obj\ $(XSLT_INTDIR)\transform.obj\ $(XSLT_INTDIR)\variables.obj\ $(XSLT_INTDIR)\xslt.obj\ + $(XSLT_INTDIR)\xsltlocale.obj\ $(XSLT_INTDIR)\xsltutils.obj\ $(XSLT_INTDIR)\attrvt.obj @@ -110,6 +112,7 @@ XSLT_OBJS_A = $(XSLT_INTDIR_A)\attributes.obj\ $(XSLT_INTDIR_A)\transform.obj\ $(XSLT_INTDIR_A)\variables.obj\ $(XSLT_INTDIR_A)\xslt.obj\ + $(XSLT_INTDIR_A)\xsltlocale.obj\ $(XSLT_INTDIR_A)\xsltutils.obj\ $(XSLT_INTDIR_A)\attrvt.obj -- 2.7.4