socsvn commit: r269097 - in soc2014/ghostmansd/src/lib/libc: locale string
ghostmansd at FreeBSD.org
ghostmansd at FreeBSD.org
Wed Jun 4 23:14:21 UTC 2014
Author: ghostmansd
Date: Wed Jun 4 23:14:20 2014
New Revision: 269097
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269097
Log:
switch from strcoll_l to wcscoll_l
Reimplementation of the patch proposed by Konrad Jankowski.
The idea is to process Unicode characters rather than bytes sequences.
So we convert multi-byte sequences to Unicode sequences using functions
that support extended locales and call wcscoll_l rather than strcoll_l.
Modified:
soc2014/ghostmansd/src/lib/libc/locale/collate.c
soc2014/ghostmansd/src/lib/libc/string/strcoll.c
Modified: soc2014/ghostmansd/src/lib/libc/locale/collate.c
==============================================================================
--- soc2014/ghostmansd/src/lib/libc/locale/collate.c Wed Jun 4 22:22:46 2014 (r269096)
+++ soc2014/ghostmansd/src/lib/libc/locale/collate.c Wed Jun 4 23:14:20 2014 (r269097)
@@ -294,6 +294,28 @@
*sec = __collate_char_pri_table[*t].sec;
}
+wchar_t *
+__collate_mbstowcs(const char *str, locale_t locale)
+{
+ static const mbstate_t st_init;
+ size_t len = 0;
+ wchar_t *wcs = NULL;
+ const char *mbs = str;
+ mbstate_t st_curr = st_init;
+
+ FIX_LOCALE(locale);
+ len = mbsrtowcs(NULL, &ptr, 0, &st_curr, locale);
+ if (len == (size_t) -1)
+ return NULL;
+ wcs = (wchar_t*) malloc((len + 1) * sizeof(wchar_t));
+ if (wcs == NULL)
+ __collate_err(EX_OSERR, __func__);
+ st_curr = st_init;
+ mbsrtowcs(wcs, &mbs, len, &st_curr, locale);
+ wcs[len] = L'\0';
+ return wcs;
+}
+
u_char *
__collate_strdup(u_char *s)
{
Modified: soc2014/ghostmansd/src/lib/libc/string/strcoll.c
==============================================================================
--- soc2014/ghostmansd/src/lib/libc/string/strcoll.c Wed Jun 4 22:22:46 2014 (r269096)
+++ soc2014/ghostmansd/src/lib/libc/string/strcoll.c Wed Jun 4 23:14:20 2014 (r269097)
@@ -40,57 +40,28 @@
#include <stdio.h>
int
-strcoll_l(const char *s, const char *s2, locale_t locale)
+strcoll_l(const char *mbs1, const char *mbs2, locale_t locale)
{
- int len, len2, prim, prim2, sec, sec2, ret, ret2;
- const char *t, *t2;
- char *tt, *tt2;
+ int ret = 0;
+ wchar_t *wcs1 = NULL;
+ wchar_t *wcs2 = NULL;
+
FIX_LOCALE(locale);
struct xlocale_collate *table =
(struct xlocale_collate*)locale->components[XLC_COLLATE];
- if (table->__collate_load_error)
- return strcmp(s, s2);
-
- len = len2 = 1;
- ret = ret2 = 0;
- if (table->__collate_substitute_nontrivial) {
- t = tt = __collate_substitute(table, s);
- t2 = tt2 = __collate_substitute(table, s2);
- } else {
- tt = tt2 = NULL;
- t = s;
- t2 = s2;
- }
- while(*t && *t2) {
- prim = prim2 = 0;
- while(*t && !prim) {
- __collate_lookup(table, t, &len, &prim, &sec);
- t += len;
- }
- while(*t2 && !prim2) {
- __collate_lookup(table, t2, &len2, &prim2, &sec2);
- t2 += len2;
- }
- if(!prim || !prim2)
- break;
- if(prim != prim2) {
- ret = prim - prim2;
- goto end;
- }
- if(!ret2)
- ret2 = sec - sec2;
+ if ((table->__collate_load_error)
+ || (wcs1 = __collate_mbstowcs(mbs1, locale) == NULL)
+ || (wcs2 = __collate_mbstowcs(mbs2, locale) == NULL))
+ {
+ free(wcs1);
+ free(wcs2);
+ return strcmp(mbs1, mbs2);
}
- if(!*t && *t2)
- ret = -(int)((u_char)*t2);
- else if(*t && !*t2)
- ret = (u_char)*t;
- else if(!*t && !*t2)
- ret = ret2;
- end:
- free(tt);
- free(tt2);
+ ret = wcscoll_l(wcs1, wcs2, locale);
+ free(whls);
+ free(wcs2);
return ret;
}
More information about the svn-soc-all
mailing list