Print this page
2964 need POSIX 2008 locale object support
@@ -4,10 +4,15 @@
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Paul Borman at Krystal Technologies.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
@@ -45,22 +50,28 @@
#include "mblocal.h"
#include "setlocale.h"
#include "_ctype.h"
#include "../i18n/_locale.h"
+/*
+ * A cached version of the runes for this thread. Used by ctype.h
+ */
+__thread const _RuneLocale *_ThreadRuneLocale;
+
extern _RuneLocale *_Read_RuneMagi(FILE *);
extern unsigned char __ctype_C[];
-static int __setrunelocale(const char *);
+static int __setrunelocale(struct xlocale_ctype *, const char *);
static int
-__setrunelocale(const char *encoding)
+__setrunelocale(struct xlocale_ctype *l, const char *encoding)
{
FILE *fp;
char name[PATH_MAX];
_RuneLocale *rl;
int saverr, ret;
+ struct xlocale_ctype saved = *l; /* XXX DOUBLE NOT USED */
size_t (*old__mbrtowc)(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
size_t (*old__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
int (*old__mbsinit)(const mbstate_t *);
@@ -96,25 +107,25 @@
__ctype_mask[i] = _DefaultRuneLocale.__runetype[i];
__trans_upper[i] = _DefaultRuneLocale.__mapupper[i];
__trans_lower[i] = _DefaultRuneLocale.__maplower[i];
}
- (void) _none_init(&_DefaultRuneLocale);
+ (void) _none_init(l, &_DefaultRuneLocale);
return (0);
}
/*
* If the locale name is the same as our cache, use the cache.
*/
if (CachedRuneLocale != NULL &&
strcmp(encoding, ctype_encoding) == 0) {
- _CurrentRuneLocale = CachedRuneLocale;
- __mbrtowc = Cached__mbrtowc;
- __mbsinit = Cached__mbsinit;
- __mbsnrtowcs = Cached__mbsnrtowcs;
- __wcrtomb = Cached__wcrtomb;
- __wcsnrtombs = Cached__wcsnrtombs;
+ l->runes = CachedRuneLocale;
+ l->__mbrtowc = Cached__mbrtowc;
+ l->__mbsinit = Cached__mbsinit;
+ l->__mbsnrtowcs = Cached__mbsnrtowcs;
+ l->__wcrtomb = Cached__wcrtomb;
+ l->__wcsnrtombs = Cached__wcsnrtombs;
return (0);
}
/*
* Slurp the locale file into the cache.
@@ -137,18 +148,18 @@
old__mbsinit = __mbsinit;
old__mbsnrtowcs = __mbsnrtowcs;
old__wcrtomb = __wcrtomb;
old__wcsnrtombs = __wcsnrtombs;
- __mbrtowc = NULL;
- __mbsinit = NULL;
- __mbsnrtowcs = __mbsnrtowcs_std;
- __wcrtomb = NULL;
- __wcsnrtombs = __wcsnrtombs_std;
+ l->__mbrtowc = NULL;
+ l->__mbsinit = NULL;
+ l->__mbsnrtowcs = __mbsnrtowcs_std;
+ l->__wcrtomb = NULL;
+ l->__wcsnrtombs = __wcsnrtombs_std;
if (strcmp(rl->__encoding, "NONE") == 0)
- ret = _none_init(rl);
+ ret = _none_init(l, rl);
else if (strcmp(rl->__encoding, "UTF-8") == 0)
ret = _UTF8_init(rl);
else if (strcmp(rl->__encoding, "EUC-CN") == 0)
ret = _EUC_CN_init(rl);
else if (strcmp(rl->__encoding, "EUC-JP") == 0)
@@ -172,16 +183,16 @@
if (ret == 0) {
if (CachedRuneLocale != NULL) {
free(CachedRuneLocale);
}
- CachedRuneLocale = _CurrentRuneLocale;
- Cached__mbrtowc = __mbrtowc;
- Cached__mbsinit = __mbsinit;
- Cached__mbsnrtowcs = __mbsnrtowcs;
- Cached__wcrtomb = __wcrtomb;
- Cached__wcsnrtombs = __wcsnrtombs;
+ CachedRuneLocale = l->runes;
+ Cached__mbrtowc = l->__mbrtowc;
+ Cached__mbsinit = l->__mbsinit;
+ Cached__mbsnrtowcs = l->__mbsnrtowcs;
+ Cached__wcrtomb = l->__wcrtomb;
+ Cached__wcsnrtombs = l->__wcsnrtombs;
(void) strcpy(ctype_encoding, encoding);
/*
* We need to overwrite the _ctype array. This requires
* some finagling. This is because references to it may
@@ -226,27 +237,53 @@
/*
* Note that we expect the init code will have populated
* the CSWIDTH array (__ctype[514-520]) properly.
*/
} else {
- __mbrtowc = old__mbrtowc;
- __mbsinit = old__mbsinit;
- __mbsnrtowcs = old__mbsnrtowcs;
- __wcrtomb = old__wcrtomb;
- __wcsnrtombs = old__wcsnrtombs;
+ l->__mbrtowc = old__mbrtowc;
+ l->__mbsinit = old__mbsinit;
+ l->__mbsnrtowcs = old__mbsnrtowcs;
+ l->__wcrtomb = old__wcrtomb;
+ l->__wcsnrtombs = old__wcsnrtombs;
free(rl);
}
return (ret);
}
int
__wrap_setrunelocale(const char *locale)
{
- int ret = __setrunelocale(locale);
+ int ret = __setrunelocale(&__xlocale_global_ctype, locale);
if (ret != 0) {
errno = ret;
return (_LDP_ERROR);
}
+ /* XXX */
+// __mb_cur_max = __xlocale_global_ctype.__mb_cur_max;
+// __mb_sb_limit = __xlocale_global_ctype.__mb_sb_limit;
+ _CurrentRuneLocale = __xlocale_global_ctype.runes;
return (_LDP_LOADED);
}
+
+void
+__set_thread_rune_locale(locale_t loc)
+{
+
+ if (loc == NULL) {
+ _ThreadRuneLocale = &_DefaultRuneLocale;
+ } else {
+ _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes;
+ }
+}
+
+void *
+__ctype_load(const char *locale, locale_t unused)
+{
+ struct xlocale_ctype *l;
+
+ l = calloc(sizeof(struct xlocale_ctype), 1);
+ /* XXX */
+
+ return (l);
+}