socsvn commit: r272578 - in soc2014/ghostmansd/head/lib/libc: locale string unicode

ghostmansd at FreeBSD.org ghostmansd at FreeBSD.org
Sun Aug 17 23:06:20 UTC 2014


Author: ghostmansd
Date: Sun Aug 17 23:06:16 2014
New Revision: 272578
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272578

Log:
  various fixes and improvements
  
  wcscoll() and wcsxfrm() shall now work as expected

Modified:
  soc2014/ghostmansd/head/lib/libc/locale/xlocale.c
  soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h
  soc2014/ghostmansd/head/lib/libc/string/wcscoll.c
  soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c
  soc2014/ghostmansd/head/lib/libc/unicode/coll.h
  soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c
  soc2014/ghostmansd/head/lib/libc/unicode/ucsnorm.c
  soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c

Modified: soc2014/ghostmansd/head/lib/libc/locale/xlocale.c
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/locale/xlocale.c	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/locale/xlocale.c	Sun Aug 17 23:06:16 2014	(r272578)
@@ -37,6 +37,8 @@
 #include <db.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <errno.h>
+#include <arpa/inet.h>
 #include "libc_private.h"
 #include "xlocale_private.h"
 
@@ -54,6 +56,10 @@
 void *__colldb_root_handle(void)
 {
 	_once(&colldb_root_once, &colldb_root_init);
+	if (colldb_root_handle == NULL) {
+		errno = ENOSYS;
+		return (NULL);
+	}
 	return (colldb_root_handle);
 }
 
@@ -276,6 +282,7 @@
 		value->weights[i].level3 = ntohl(weights[i].level3);
 		value->weights[i].level4 = ntohl(weights[i].level4);
 	}
+	free(dbvalue.data);
 	free(keybuf);
 	return (0);
 }

Modified: soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h	Sun Aug 17 23:06:16 2014	(r272578)
@@ -53,7 +53,7 @@
 size_t	__ucsnorm(uint32_t*, const uint32_t*, size_t, int);
 
 #define	__COLLDB_VERSION	0x00000001
-#define	__COLLDB_WEIGHTS_MAX	10
+#define	__COLLDB_WEIGHTS_MAX	16
 struct __colldb_weight {
 	uint8_t alternate;
 	uint32_t level1;

Modified: soc2014/ghostmansd/head/lib/libc/string/wcscoll.c
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/string/wcscoll.c	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/string/wcscoll.c	Sun Aug 17 23:06:16 2014	(r272578)
@@ -78,9 +78,11 @@
 	struct xlocale_collate *table =
 		(struct xlocale_collate*)locale->components[XLC_COLLATE];
 
+	errno = 0;
 	diff = __ucscoll(ucs1, ucs2, locale->colldb);
-	if (errno == init_error)
-		return diff;
+	if (errno != ENOSYS)
+		return (diff);
+	errno = init_error;
 
 	if (table->__collate_load_error || MB_CUR_MAX > 1)
 		/*

Modified: soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c	Sun Aug 17 23:06:16 2014	(r272578)
@@ -37,6 +37,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <stdlib.h>
+#include <errno.h>
 #include <string.h>
 #include <wchar.h>
 #include "collate.h"
@@ -58,9 +59,11 @@
 	struct xlocale_collate *table =
 		(struct xlocale_collate*)locale->components[XLC_COLLATE];
 
+	errno = 0;
 	ulen = __ucsxfrm(udst, usrc, len, locale->colldb);
-	if (errno == init_errno)
+	if (errno != ENOSYS)
 		return (ulen);
+	errno = init_error;
 
 	if (*src == L'\0') {
 		if (len != 0)

Modified: soc2014/ghostmansd/head/lib/libc/unicode/coll.h
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/unicode/coll.h	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/unicode/coll.h	Sun Aug 17 23:06:16 2014	(r272578)
@@ -28,6 +28,8 @@
 #include "xlocale_private.h"
 
 
+#include <stdio.h>
+
 static size_t
 __coll_iter(const uint32_t *iter, void *colldb, struct __colldb_value *val,
 	    struct __colldb_weight default_weights[2])
@@ -36,10 +38,9 @@
 	size_t shift = 0;
 	struct __colldb_key key;
 
-	for (shift = 1; shift != 18; ++shift)
-	{
+	for (shift = 1; shift < 18; ++shift) {
 		if (*(iter + shift - 1) == 0)
-			break;
+			continue;
 		key.count = shift;
 		key.chars = iter;
 		state = __colldb_get(colldb, &key, val);
@@ -49,12 +50,10 @@
 			break;
 	}
 
-	if ((state != 0) && (colldb != __colldb_root))
-	{
-		for (shift = 1; shift != 18; ++shift)
-		{
+	if ((state != 0) && (colldb != __colldb_root)) {
+		for (shift = 1; shift < 18; ++shift) {
 			if (*(iter + shift - 1) == 0)
-				break;
+				continue;
 			key.count = shift;
 			key.chars = iter;
 			state = __colldb_get(__colldb_root, &key, val);
@@ -65,8 +64,7 @@
 		}
 	}
 
-	if (state != 0)
-	{
+	if (state != 0) {
 		shift = 1;
 		default_weights[0].level1 = 0xFBC0;
 		if (((0x4E00 <= *iter) && (*iter <= 0x9FCC)) ||

Modified: soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c	Sun Aug 17 23:06:16 2014	(r272578)
@@ -36,28 +36,29 @@
 int
 __ucscoll(const uint32_t *lstr, const uint32_t *rstr, void *colldb)
 {
-	int cmp = 0;
 	size_t i = 0;
 	int state = 0;
 	int error = 0;
+	size_t count = 0;
 	size_t size[2] = {0, 0};
 	size_t shift[2] = {0, 0};
 	struct __colldb_value val[2];
-	uint32_t *str[2] = {NULL, NULL};
 	uint32_t *norm[2] = {NULL, NULL};
 	uint32_t *iter[2] = {NULL, NULL};
+	const uint32_t *str[2] = {lstr, rstr};
 	struct __colldb_weight default_weights[2][2];
 	struct __colldb_weight weights[2][__COLLDB_WEIGHTS_MAX];
 	const int init_error = errno;
 
-	fprintf(stderr, "ucscoll\n");
 	if ((lstr == NULL) || (rstr == NULL)) {
 		errno = EINVAL;
 		return (0);
 	}
-	if (colldb == NULL)
-		colldb = __colldb_root;
-	fprintf(stderr, "root=%p\n", colldb);
+	if (colldb == NULL) {
+		colldb = __colldb_open("/usr/share/locale/UTF-8/LC_COLLATE");
+		if (colldb == NULL)
+			return (0);
+	}
 	for (i = 0; i < 2; ++i) {
 		size[i] = __ucsnorm(NULL, str[i], 0, __UC_NFD);
 		norm[i] = malloc(size[i] * sizeof(uint32_t));
@@ -68,22 +69,26 @@
 			errno = error;
 			return (0);
 		}
+		__ucscanon(norm[i]);
+		memset(weights[i], 0, (__COLLDB_WEIGHTS_MAX * sizeof(struct __colldb_weight)));
+		memset(default_weights[i], 0, (2 * sizeof(struct __colldb_weight)));
 		iter[i] = norm[i];
 	}
 
 	if (colldb == NULL)
 		colldb = __colldb_root;
-	while (*iter[0] != 0) {
-		if (*iter[1] == 0) {
+	while (*(iter[0]) != 0) {
+		if (*(iter[1]) == 0) {
 			free(norm[0]);
 			free(norm[1]);
+			errno = init_error;
 			return (+1);
 		}
 		for (i = 0; i < 2; ++i) {
 			val[i].weights = weights[i];
 			val[i].count = __COLLDB_WEIGHTS_MAX;
-			shift[i] = __coll_iter(iter[0], colldb, &val[i],
-			    default_weights[i]);
+			shift[i] = __coll_iter(iter[i], colldb, &val[i],
+					       default_weights[i]);
 			if (shift[i] == 0) {
 				error = errno;
 				free(norm[0]);
@@ -91,28 +96,38 @@
 				errno = error;
 				return (0);
 			}
+			iter[i] += shift[i];
 		}
-		iter[i] += shift[i];
 		if (val[0].count < val[1].count)
-			cmp = val[0].count;
+			count = val[0].count;
 		else
-			cmp = val[1].count;
-		for (i = 0; i < cmp; ++i) {
-			state = memcmp(&val[0].weights[i], &val[1].weights[i],
-			    sizeof(struct __colldb_weight));
-			if (state != 0) {
+			count = val[1].count;
+
+		for (i = 0; i < count; ++i) {
+			state = memcmp((val[0].weights + i),
+				       (val[1].weights + i),
+				       sizeof(struct __colldb_weight));
+			if ((state != 0) || (val[0].count != val[1].count)) {
+				if (val[0].count < val[1].count)
+					state = -1;
+				else if (val[0].count > val[1].count)
+					state = +1;
 				free(norm[0]);
 				free(norm[1]);
 				errno = init_error;
 				return (state);
 			}
 		}
-		if (val[0].count < val[1].count)
-			state = -1;
-		else if (val[0].count > val[1].count)
-			state = +1;
 	}
-	if (*iter[1] != 0)
+	if (*iter[1] != 0) {
+		free(norm[0]);
+		free(norm[1]);
+		errno = init_error;
 		return (-1);
+	}
+	free(norm[0]);
+	free(norm[1]);
+	__colldb_close(colldb);
+	errno = init_error;
 	return (0);
 }

Modified: soc2014/ghostmansd/head/lib/libc/unicode/ucsnorm.c
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/unicode/ucsnorm.c	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/unicode/ucsnorm.c	Sun Aug 17 23:06:16 2014	(r272578)
@@ -82,56 +82,58 @@
 static size_t
 decompose(uint32_t *buffer, const uint32_t *str, size_t size, int compat)
 {
+	size_t lsize = 0;
+	size_t rsize = 0;
 	uint32_t code = 0;
-	uint32_t tmpbuf[20];
-	uint32_t segbuf[20];
 	size_t reqsize = 0;
-	size_t tmpsize = 0;
-	size_t segsize = 0;
+	uint32_t *ptr = NULL;
+	uint32_t lbuf[20] = {0};
+	uint32_t rbuf[20] = {0};
+	uint32_t *lptr = lbuf;
+	uint32_t *rptr = rbuf;
 	const uint32_t *iter = str;
-	const uint32_t *segptr = segbuf;
+	const uint32_t *xptr = NULL;
 
 	for (; *iter != 0; ++iter) {
 		code = *iter;
-		segsize = 1;
-		segptr = iter;
+		lsize = 1;
+		xptr = iter;
 		if ((HANGUL_SBASE <= code) && (code < (HANGUL_SBASE + HANGUL_SCOUNT))) {
 			code -= HANGUL_SBASE;
 			if (code < HANGUL_SCOUNT) {
-				segbuf[0] = (HANGUL_LBASE + (code / HANGUL_NCOUNT));
-				segbuf[1] = (HANGUL_VBASE + ((code % HANGUL_NCOUNT) / HANGUL_TCOUNT));
-				segbuf[2] = (HANGUL_TBASE + (code % HANGUL_TCOUNT));
-				segsize = ((segptr[2] == HANGUL_TBASE) ? 2 : 3);
+				lbuf[0] = (HANGUL_LBASE + (code / HANGUL_NCOUNT));
+				lbuf[1] = (HANGUL_VBASE + ((code % HANGUL_NCOUNT) / HANGUL_TCOUNT));
+				lbuf[2] = (HANGUL_TBASE + (code % HANGUL_TCOUNT));
+				lsize = ((xptr[2] == HANGUL_TBASE) ? 2 : 3);
 			} else
-				segbuf[0] = *iter;
+				lbuf[0] = *iter;
 		} else if ((DECOMPOSITION_MIN <= code) && (code <= DECOMPOSITION_MAX)) {
-			segptr = decompose_base(&code, &segsize, compat);
-			if (segptr != &code) {
-				segsize *= sizeof(uint32_t);
-				memcpy(segbuf, segptr, segsize);
-				segsize /= sizeof(uint32_t);
-				segptr = segbuf;
-				while (tmpsize != segsize) {
-					tmpsize = segsize;
-					tmpbuf[segsize] = 0;
-					segsize *= sizeof(uint32_t);
-					memcpy(tmpbuf, segbuf, segsize);
-					segsize /= sizeof(uint32_t);
-					segsize = decompose(tmpbuf, segbuf, 20, compat);
-				}
+			xptr = decompose_base(&code, &lsize, compat);
+			if (xptr != &code) {
+				memcpy(lbuf, xptr, (lsize * sizeof(uint32_t)));
+				do {
+					rsize = decompose(rptr, lptr, 20, compat);
+					if (lsize == rsize) {
+						xptr = rptr;
+						break;
+					}
+					ptr = lptr;
+					lptr = rptr;
+					rptr = ptr;
+				} while (1);
 			}
 		}
-		if (((reqsize + segsize + 1) > size) && (buffer != NULL)) {
+		if (((reqsize + lsize + 1) > size) && (buffer != NULL)) {
 			size = (size - reqsize - 1);
-			memcpy(buffer, segptr, (size * sizeof(uint32_t)));
+			memcpy(buffer, xptr, (size * sizeof(uint32_t)));
 			*(buffer + size) = 0;
 			return decompose(NULL, str, 0, compat);
 		}
 		if (buffer != NULL) {
-			memcpy(buffer, segptr, (segsize * sizeof(uint32_t)));
-			buffer += segsize;
+			memcpy(buffer, xptr, (lsize * sizeof(uint32_t)));
+			buffer += lsize;
 		}
-		reqsize += segsize;
+		reqsize += lsize;
 	}
 	if (buffer == NULL)
 		++reqsize;

Modified: soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c
==============================================================================
--- soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c	Sun Aug 17 21:36:37 2014	(r272577)
+++ soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c	Sun Aug 17 23:06:16 2014	(r272578)
@@ -51,8 +51,11 @@
 		errno = EINVAL;
 		return (SIZE_MAX);
 	}
-	if (colldb == NULL)
-		colldb = __colldb_root;
+	if (colldb == NULL) {
+		colldb = __colldb_open("/usr/share/locale/UTF-8/LC_COLLATE");
+		if (colldb == NULL)
+			return (0);
+	}
 	normsize = __ucsnorm(NULL, str, 0, __UC_NFD);
 	norm = malloc(normsize * sizeof(uint32_t));
 	if (norm == NULL) {
@@ -74,26 +77,24 @@
 		shift = __coll_iter(iter, colldb, &value, default_weights);
 		if (shift == 0) {
 			error = errno;
-			free(elements);
 			free(norm);
 			errno = error;
 			return (SIZE_MAX);
 		}
-		free(elements);
-		count = (value.count * 4);
-		elements = malloc(count * sizeof(uint32_t));
+		count = value.count;
+		elements = malloc(count * 4 * sizeof(uint32_t));
 		if (elements == NULL) {
-			free(elements);
 			free(norm);
 			errno = ENOMEM;
 			return (SIZE_MAX);
 		}
-		for (i = 0; i < value.count; ++i) {
+		for (i = 0; i < count; ++i) {
 			elements[(count * 0) + i] = value.weights[i].level1;
 			elements[(count * 1) + i] = value.weights[i].level2;
 			elements[(count * 2) + i] = value.weights[i].level3;
 			elements[(count * 3) + i] = value.weights[i].level4;
 		}
+		count *= 4;
 		for (i = 0; i < count; ++i)
 			elements[i] = (elements[i] ? elements[i] : 1);
 
@@ -109,6 +110,7 @@
 			memcpy(buffer, elements, (count * sizeof(uint32_t)));
 			buffer += count;
 		}
+		free(elements);
 		reqsize += count;
 		iter += shift;
 	}
@@ -118,6 +120,7 @@
 	else
 		*buffer = 0;
 	free(norm);
+	__colldb_close(colldb);
 	errno = init_error;
 	return (reqsize);
 }


More information about the svn-soc-all mailing list