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