setrunelocale.c.patch   [plain text]


--- setrunelocale.c.orig	2004-11-25 11:38:19.000000000 -0800
+++ setrunelocale.c	2005-02-17 10:00:02.000000000 -0800
@@ -37,6 +37,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.44 2004/10/18 02:06:18 ache Exp $");
 
+#include "xlocale_private.h"
+
 #include <runetype.h>
 #include <errno.h>
 #include <limits.h>
@@ -49,50 +51,43 @@
 #include "mblocal.h"
 #include "setlocale.h"
 
-extern int		_none_init(_RuneLocale *);
-extern int		_UTF8_init(_RuneLocale *);
-extern int		_EUC_init(_RuneLocale *);
-extern int		_GB18030_init(_RuneLocale *);
-extern int		_GB2312_init(_RuneLocale *);
-extern int		_GBK_init(_RuneLocale *);
-extern int		_BIG5_init(_RuneLocale *);
-extern int		_MSKanji_init(_RuneLocale *);
-extern _RuneLocale	*_Read_RuneMagi(FILE *);
-
-static int		__setrunelocale(const char *);
+extern int		_none_init(struct __xlocale_st_runelocale *);
+extern int		_UTF8_init(struct __xlocale_st_runelocale *);
+extern int		_EUC_init(struct __xlocale_st_runelocale *);
+extern int		_GB18030_init(struct __xlocale_st_runelocale *);
+extern int		_GB2312_init(struct __xlocale_st_runelocale *);
+extern int		_GBK_init(struct __xlocale_st_runelocale *);
+extern int		_BIG5_init(struct __xlocale_st_runelocale *);
+extern int		_MSKanji_init(struct __xlocale_st_runelocale *);
+extern int		_UTF2_init(struct __xlocale_st_runelocale *);	/* deprecated */
+extern struct __xlocale_st_runelocale	*_Read_RuneMagi(FILE *);
+
+/* depreciated interfaces */
+rune_t	sgetrune(const char *, size_t, char const **);
+int	sputrune(rune_t, char *, size_t, char **);
 
-static int
-__setrunelocale(const char *encoding)
+__private_extern__ int
+__setrunelocale(const char *encoding, locale_t loc)
 {
 	FILE *fp;
 	char name[PATH_MAX];
+	struct __xlocale_st_runelocale *xrl;
 	_RuneLocale *rl;
 	int saverr, ret;
-	static char ctype_encoding[ENCODING_LEN + 1];
-	static _RuneLocale *CachedRuneLocale;
-	static int Cached__mb_cur_max;
-	static size_t (*Cached__mbrtowc)(wchar_t * __restrict,
-	    const char * __restrict, size_t, mbstate_t * __restrict);
-	static size_t (*Cached__wcrtomb)(char * __restrict, wchar_t,
-	    mbstate_t * __restrict);
-	static int (*Cached__mbsinit)(const mbstate_t *);
-	static size_t (*Cached__mbsnrtowcs)(wchar_t * __restrict,
-	    const char ** __restrict, size_t, size_t, mbstate_t * __restrict);
-	static size_t (*Cached__wcsnrtombs)(char * __restrict,
-	    const wchar_t ** __restrict, size_t, size_t,
-	    mbstate_t * __restrict);
+	static struct __xlocale_st_runelocale *CachedRuneLocale;
+	extern int __mb_cur_max;
 
 	/*
 	 * The "C" and "POSIX" locale are always here.
 	 */
 	if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) {
-		_CurrentRuneLocale = &_DefaultRuneLocale;
-		__mb_cur_max = 1;
-		__mbrtowc = _none_mbrtowc;
-		__mbsinit = _none_mbsinit;
-		__mbsnrtowcs = _none_mbsnrtowcs;
-		__wcrtomb = _none_wcrtomb;
-		__wcsnrtombs = _none_wcsnrtombs;
+		XL_RELEASE(loc->__lc_ctype);
+		loc->__lc_ctype = &_DefaultRuneXLocale;
+		/* no need to retain _DefaultRuneXLocale */
+		if (loc == &__global_locale) {
+			_CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale;
+			__mb_cur_max = loc->__lc_ctype->__mb_cur_max;
+		}
 		return (0);
 	}
 
@@ -100,14 +95,14 @@
 	 * If the locale name is the same as our cache, use the cache.
 	 */
 	if (CachedRuneLocale != NULL &&
-	    strcmp(encoding, ctype_encoding) == 0) {
-		_CurrentRuneLocale = CachedRuneLocale;
-		__mb_cur_max = Cached__mb_cur_max;
-		__mbrtowc = Cached__mbrtowc;
-		__mbsinit = Cached__mbsinit;
-		__mbsnrtowcs = Cached__mbsnrtowcs;
-		__wcrtomb = Cached__wcrtomb;
-		__wcsnrtombs = Cached__wcsnrtombs;
+	    strcmp(encoding, CachedRuneLocale->__ctype_encoding) == 0) {
+		XL_RELEASE(loc->__lc_ctype);
+		loc->__lc_ctype = CachedRuneLocale;
+		XL_RETAIN(loc->__lc_ctype);
+		if (loc == &__global_locale) {
+			_CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale;
+			__mb_cur_max = loc->__lc_ctype->__mb_cur_max;
+		}
 		return (0);
 	}
 
@@ -124,63 +119,72 @@
 	if ((fp = fopen(name, "r")) == NULL)
 		return (errno == 0 ? ENOENT : errno);
 
-	if ((rl = _Read_RuneMagi(fp)) == NULL) {
+	if ((xrl = _Read_RuneMagi(fp)) == NULL) {
 		saverr = (errno == 0 ? EFTYPE : errno);
 		(void)fclose(fp);
 		return (saverr);
 	}
 	(void)fclose(fp);
 
-	__mbrtowc = NULL;
-	__mbsinit = NULL;
-	__mbsnrtowcs = __mbsnrtowcs_std;
-	__wcrtomb = NULL;
-	__wcsnrtombs = __wcsnrtombs_std;
-	rl->__sputrune = NULL;
-	rl->__sgetrune = NULL;
+	xrl->__mbrtowc = NULL;
+	xrl->__mbsinit = NULL;
+	xrl->__mbsnrtowcs = __mbsnrtowcs_std;
+	xrl->__wcrtomb = NULL;
+	xrl->__wcsnrtombs = __wcsnrtombs_std;
+
+	rl = &xrl->_CurrentRuneLocale;
+
+	/* provide backwards compatibility (depreciated interface) */
+	rl->__sputrune = sputrune;
+	rl->__sgetrune = sgetrune;
+
 	if (strcmp(rl->__encoding, "NONE") == 0)
-		ret = _none_init(rl);
+		ret = _none_init(xrl);
 	else if (strcmp(rl->__encoding, "UTF-8") == 0)
-		ret = _UTF8_init(rl);
+		ret = _UTF8_init(xrl);
 	else if (strcmp(rl->__encoding, "EUC") == 0)
-		ret = _EUC_init(rl);
+		ret = _EUC_init(xrl);
  	else if (strcmp(rl->__encoding, "GB18030") == 0)
- 		ret = _GB18030_init(rl);
+ 		ret = _GB18030_init(xrl);
 	else if (strcmp(rl->__encoding, "GB2312") == 0)
-		ret = _GB2312_init(rl);
+		ret = _GB2312_init(xrl);
 	else if (strcmp(rl->__encoding, "GBK") == 0)
-		ret = _GBK_init(rl);
+		ret = _GBK_init(xrl);
 	else if (strcmp(rl->__encoding, "BIG5") == 0)
-		ret = _BIG5_init(rl);
+		ret = _BIG5_init(xrl);
 	else if (strcmp(rl->__encoding, "MSKanji") == 0)
-		ret = _MSKanji_init(rl);
+		ret = _MSKanji_init(xrl);
+	else if (strcmp(rl->__encoding, "UTF2") == 0)
+		ret = _UTF2_init(xrl);
 	else
 		ret = EFTYPE;
 	if (ret == 0) {
-		if (CachedRuneLocale != NULL) {
-			/* See euc.c */
-			if (strcmp(CachedRuneLocale->__encoding, "EUC") == 0)
-				free(CachedRuneLocale->__variable);
-			free(CachedRuneLocale);
+		(void)strcpy(xrl->__ctype_encoding, encoding);
+		XL_RELEASE(loc->__lc_ctype);
+		loc->__lc_ctype = xrl;
+		if (loc == &__global_locale) {
+			_CurrentRuneLocale = &loc->__lc_ctype->_CurrentRuneLocale;
+			__mb_cur_max = loc->__lc_ctype->__mb_cur_max;
 		}
-		CachedRuneLocale = _CurrentRuneLocale;
-		Cached__mb_cur_max = __mb_cur_max;
-		Cached__mbrtowc = __mbrtowc;
-		Cached__mbsinit = __mbsinit;
-		Cached__mbsnrtowcs = __mbsnrtowcs;
-		Cached__wcrtomb = __wcrtomb;
-		Cached__wcsnrtombs = __wcsnrtombs;
-		(void)strcpy(ctype_encoding, encoding);
+		XL_RELEASE(CachedRuneLocale);
+		CachedRuneLocale = xrl;
+		XL_RETAIN(CachedRuneLocale);
 	} else
-		free(rl);
+		XL_RELEASE(xrl);
 
 	return (ret);
 }
 
 int
-__wrap_setrunelocale(const char *locale)
+setrunelocale(const char *encoding)
+{
+	return __setrunelocale(encoding, &__global_locale);
+}
+
+__private_extern__ int
+__wrap_setrunelocale(const char *locale, locale_t loc)
 {
-	int ret = __setrunelocale(locale);
+	int ret = __setrunelocale(locale, loc);
 
 	if (ret != 0) {
 		errno = ret;