Module Name: src
Committed By: joerg
Date: Fri Sep 13 13:13:32 UTC 2013
Modified Files:
src/lib/libc/citrus: citrus_lc_ctype.c
src/lib/libc/compat/locale: compat_setlocale1.c
src/lib/libc/locale: global_locale.c localeconv.c nb_lc_messages_misc.h
nb_lc_monetary_misc.h nb_lc_numeric_misc.h nb_lc_template.h
nb_lc_template_decl.h nb_lc_time_misc.h newlocale.c setlocale.c
setlocale_local.h
Log Message:
Redo the locale cache to be constant. It now contains the localeconv()
data and which LC_MONETARY and LC_NUMERIC values it is derived from.
In newlocale(3) and setlocale(3), check for the existing entries and on
miss, create a new entry. This is currently not using a lock for the
list as the worst case is a small memory leak.
To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/lib/libc/citrus/citrus_lc_ctype.c
cvs rdiff -u -r1.1 -r1.2 src/lib/libc/compat/locale/compat_setlocale1.c
cvs rdiff -u -r1.20 -r1.21 src/lib/libc/locale/global_locale.c
cvs rdiff -u -r1.21 -r1.22 src/lib/libc/locale/localeconv.c
cvs rdiff -u -r1.6 -r1.7 src/lib/libc/locale/nb_lc_messages_misc.h \
src/lib/libc/locale/nb_lc_monetary_misc.h \
src/lib/libc/locale/nb_lc_numeric_misc.h
cvs rdiff -u -r1.7 -r1.8 src/lib/libc/locale/nb_lc_template.h \
src/lib/libc/locale/nb_lc_time_misc.h
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/locale/nb_lc_template_decl.h
cvs rdiff -u -r1.2 -r1.3 src/lib/libc/locale/newlocale.c
cvs rdiff -u -r1.63 -r1.64 src/lib/libc/locale/setlocale.c
cvs rdiff -u -r1.14 -r1.15 src/lib/libc/locale/setlocale_local.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/citrus/citrus_lc_ctype.c
diff -u src/lib/libc/citrus/citrus_lc_ctype.c:1.14 src/lib/libc/citrus/citrus_lc_ctype.c:1.15
--- src/lib/libc/citrus/citrus_lc_ctype.c:1.14 Tue Aug 20 19:58:30 2013
+++ src/lib/libc/citrus/citrus_lc_ctype.c Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: citrus_lc_ctype.c,v 1.14 2013/08/20 19:58:30 joerg Exp $ */
+/* $NetBSD: citrus_lc_ctype.c,v 1.15 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: citrus_lc_ctype.c,v 1.14 2013/08/20 19:58:30 joerg Exp $");
+__RCSID("$NetBSD: citrus_lc_ctype.c,v 1.15 2013/09/13 13:13:32 joerg Exp $");
#endif /* LIBC_SCCS and not lint */
#include "reentrant.h"
@@ -96,14 +96,6 @@ _citrus_LC_CTYPE_create_impl(const char
}
static __inline void
-_PREFIX(build_cache)(struct _locale_cache_t * __restrict cache,
- _RuneLocale * __restrict data)
-{
- _DIAGASSERT(cache != NULL);
- _DIAGASSERT(data != NULL);
-}
-
-static __inline void
_PREFIX(update_global)(_RuneLocale *data)
{
_DIAGASSERT(data != NULL);
Index: src/lib/libc/compat/locale/compat_setlocale1.c
diff -u src/lib/libc/compat/locale/compat_setlocale1.c:1.1 src/lib/libc/compat/locale/compat_setlocale1.c:1.2
--- src/lib/libc/compat/locale/compat_setlocale1.c:1.1 Mon Jun 7 13:52:30 2010
+++ src/lib/libc/compat/locale/compat_setlocale1.c Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: compat_setlocale1.c,v 1.1 2010/06/07 13:52:30 tnozaki Exp $ */
+/* $NetBSD: compat_setlocale1.c,v 1.2 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)1999 Citrus Project,
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: compat_setlocale1.c,v 1.1 2010/06/07 13:52:30 tnozaki Exp $");
+__RCSID("$NetBSD: compat_setlocale1.c,v 1.2 2013/09/13 13:13:32 joerg Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -38,6 +38,8 @@ __RCSID("$NetBSD: compat_setlocale1.c,v
#include "setlocale_local.h"
+#undef setlocale
+
__warn_references(setlocale,
"warning: reference to compatibility setlocale();"
"include <locale.h> for correct reference")
@@ -47,7 +49,10 @@ __warn_references(setlocale,
* This function will ensure binary compatibility for old executables.
*/
char *
-setlocale(int category, const char *locale)
+compat_setlocale(int category, const char *locale) __RENAME(setlocale);
+
+char *
+compat_setlocale(int category, const char *locale)
{
/* locale may be NULL */
Index: src/lib/libc/locale/global_locale.c
diff -u src/lib/libc/locale/global_locale.c:1.20 src/lib/libc/locale/global_locale.c:1.21
--- src/lib/libc/locale/global_locale.c:1.20 Tue Aug 20 19:58:30 2013
+++ src/lib/libc/locale/global_locale.c Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: global_locale.c,v 1.20 2013/08/20 19:58:30 joerg Exp $ */
+/* $NetBSD: global_locale.c,v 1.21 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: global_locale.c,v 1.20 2013/08/20 19:58:30 joerg Exp $");
+__RCSID("$NetBSD: global_locale.c,v 1.21 2013/09/13 13:13:32 joerg Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -110,7 +110,10 @@ static const _TimeLocale _DefaultTimeLoc
"%I:%M:%S %p"
};
-static const struct lconv _C_ldata = {
+static const char _lc_C_locale_name[] = _C_LOCALE;
+
+__dso_hidden const struct _locale_cache_t _C_cache = {
+ .ldata = {
.decimal_point = __UNCONST("."),
.thousands_sep = __UNCONST(""),
.grouping = __UNCONST(""),
@@ -135,23 +138,22 @@ static const struct lconv _C_ldata = {
.int_n_sep_by_space = NBCHAR_MAX,
.int_p_sign_posn = NBCHAR_MAX,
.int_n_sign_posn = NBCHAR_MAX,
-};
-
-static struct _locale_cache_t _global_cache = {
- .ldata = __UNCONST(&_C_ldata),
+ },
+ .monetary_name = _lc_C_locale_name,
+ .numeric_name = _lc_C_locale_name,
};
__dso_protected struct _locale _lc_global_locale = {
- .cache = &_global_cache,
+ .cache = &_C_cache,
.query = { _C_LOCALE },
.part_name = {
- [(size_t)LC_ALL ] = _C_LOCALE,
- [(size_t)LC_COLLATE ] = _C_LOCALE,
- [(size_t)LC_CTYPE ] = _C_LOCALE,
- [(size_t)LC_MONETARY] = _C_LOCALE,
- [(size_t)LC_NUMERIC ] = _C_LOCALE,
- [(size_t)LC_TIME ] = _C_LOCALE,
- [(size_t)LC_MESSAGES] = _C_LOCALE,
+ [(size_t)LC_ALL ] = _lc_C_locale_name,
+ [(size_t)LC_COLLATE ] = _lc_C_locale_name,
+ [(size_t)LC_CTYPE ] = _lc_C_locale_name,
+ [(size_t)LC_MONETARY] = _lc_C_locale_name,
+ [(size_t)LC_NUMERIC ] = _lc_C_locale_name,
+ [(size_t)LC_TIME ] = _lc_C_locale_name,
+ [(size_t)LC_MESSAGES] = _lc_C_locale_name,
},
.part_impl = {
[(size_t)LC_ALL ] = (_locale_part_t)NULL,
@@ -169,21 +171,17 @@ __dso_protected struct _locale _lc_globa
},
};
-static const struct _locale_cache_t _C_cache = {
- .ldata = __UNCONST(&_C_ldata),
-};
-
__dso_protected const struct _locale _lc_C_locale = {
- .cache = __UNCONST(&_C_cache),
+ .cache = &_C_cache,
.query = { _C_LOCALE },
.part_name = {
- [(size_t)LC_ALL ] = _C_LOCALE,
- [(size_t)LC_COLLATE ] = _C_LOCALE,
- [(size_t)LC_CTYPE ] = _C_LOCALE,
- [(size_t)LC_MONETARY] = _C_LOCALE,
- [(size_t)LC_NUMERIC ] = _C_LOCALE,
- [(size_t)LC_TIME ] = _C_LOCALE,
- [(size_t)LC_MESSAGES] = _C_LOCALE,
+ [(size_t)LC_ALL ] = _lc_C_locale_name,
+ [(size_t)LC_COLLATE ] = _lc_C_locale_name,
+ [(size_t)LC_CTYPE ] = _lc_C_locale_name,
+ [(size_t)LC_MONETARY] = _lc_C_locale_name,
+ [(size_t)LC_NUMERIC ] = _lc_C_locale_name,
+ [(size_t)LC_TIME ] = _lc_C_locale_name,
+ [(size_t)LC_MESSAGES] = _lc_C_locale_name,
},
.part_impl = {
[(size_t)LC_ALL ] = (_locale_part_t)NULL,
Index: src/lib/libc/locale/localeconv.c
diff -u src/lib/libc/locale/localeconv.c:1.21 src/lib/libc/locale/localeconv.c:1.22
--- src/lib/libc/locale/localeconv.c:1.21 Fri May 17 12:55:57 2013
+++ src/lib/libc/locale/localeconv.c Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: localeconv.c,v 1.21 2013/05/17 12:55:57 joerg Exp $ */
+/* $NetBSD: localeconv.c,v 1.22 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: localeconv.c,v 1.21 2013/05/17 12:55:57 joerg Exp $");
+__RCSID("$NetBSD: localeconv.c,v 1.22 2013/09/13 13:13:32 joerg Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -41,11 +41,11 @@ __RCSID("$NetBSD: localeconv.c,v 1.21 20
struct lconv *
localeconv(void)
{
- return _current_cache()->ldata;
+ return localeconv_l(_current_locale());
}
struct lconv *
localeconv_l(locale_t loc)
{
- return loc->cache->ldata;
+ return __UNCONST(&loc->cache->ldata);
}
Index: src/lib/libc/locale/nb_lc_messages_misc.h
diff -u src/lib/libc/locale/nb_lc_messages_misc.h:1.6 src/lib/libc/locale/nb_lc_messages_misc.h:1.7
--- src/lib/libc/locale/nb_lc_messages_misc.h:1.6 Tue Aug 20 19:58:30 2013
+++ src/lib/libc/locale/nb_lc_messages_misc.h Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: nb_lc_messages_misc.h,v 1.6 2013/08/20 19:58:30 joerg Exp $ */
+/* $NetBSD: nb_lc_messages_misc.h,v 1.7 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -34,14 +34,6 @@
*/
#define _CATEGORY_TYPE _MessagesLocale
-static __inline void
-_PREFIX(build_cache)(struct _locale_cache_t * __restrict cache,
- _MessagesLocale * __restrict data)
-{
- _DIAGASSERT(cache != NULL);
- _DIAGASSERT(data != NULL);
-}
-
/* ARGSUSED */
static __inline void
_PREFIX(update_global)(_MessagesLocale *data)
Index: src/lib/libc/locale/nb_lc_monetary_misc.h
diff -u src/lib/libc/locale/nb_lc_monetary_misc.h:1.6 src/lib/libc/locale/nb_lc_monetary_misc.h:1.7
--- src/lib/libc/locale/nb_lc_monetary_misc.h:1.6 Tue Aug 20 19:58:30 2013
+++ src/lib/libc/locale/nb_lc_monetary_misc.h Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: nb_lc_monetary_misc.h,v 1.6 2013/08/20 19:58:30 joerg Exp $ */
+/* $NetBSD: nb_lc_monetary_misc.h,v 1.7 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -34,41 +34,6 @@
*/
#define _CATEGORY_TYPE _MonetaryLocale
-static __inline void
-_PREFIX(build_cache)(struct _locale_cache_t * __restrict cache,
- _MonetaryLocale * __restrict data)
-{
- struct lconv *ldata;
-
- _DIAGASSERT(cache != NULL);
- _DIAGASSERT(cache->ldata != NULL);
- _DIAGASSERT(data != NULL);
-
- ldata = cache->ldata;
- ldata->int_curr_symbol = __UNCONST(data->int_curr_symbol);
- ldata->currency_symbol = __UNCONST(data->currency_symbol);
- ldata->mon_decimal_point = __UNCONST(data->mon_decimal_point);
- ldata->mon_thousands_sep = __UNCONST(data->mon_thousands_sep);
- ldata->mon_grouping = __UNCONST(data->mon_grouping);
- ldata->positive_sign = __UNCONST(data->positive_sign);
- ldata->negative_sign = __UNCONST(data->negative_sign);
-
- ldata->int_frac_digits = data->int_frac_digits;
- ldata->frac_digits = data->frac_digits;
- ldata->p_cs_precedes = data->p_cs_precedes;
- ldata->p_sep_by_space = data->p_sep_by_space;
- ldata->n_cs_precedes = data->n_cs_precedes;
- ldata->n_sep_by_space = data->n_sep_by_space;
- ldata->p_sign_posn = data->p_sign_posn;
- ldata->n_sign_posn = data->n_sign_posn;
- ldata->int_p_cs_precedes = data->int_p_cs_precedes;
- ldata->int_n_cs_precedes = data->int_n_cs_precedes;
- ldata->int_p_sep_by_space = data-> int_p_sep_by_space;
- ldata->int_n_sep_by_space = data->int_n_sep_by_space;
- ldata->int_p_sign_posn = data->int_p_sign_posn;
- ldata->int_n_sign_posn = data->int_n_sign_posn;
-}
-
/* ARGSUSED */
static __inline void
_PREFIX(update_global)(_MonetaryLocale *data)
Index: src/lib/libc/locale/nb_lc_numeric_misc.h
diff -u src/lib/libc/locale/nb_lc_numeric_misc.h:1.6 src/lib/libc/locale/nb_lc_numeric_misc.h:1.7
--- src/lib/libc/locale/nb_lc_numeric_misc.h:1.6 Tue Aug 20 19:58:30 2013
+++ src/lib/libc/locale/nb_lc_numeric_misc.h Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: nb_lc_numeric_misc.h,v 1.6 2013/08/20 19:58:30 joerg Exp $ */
+/* $NetBSD: nb_lc_numeric_misc.h,v 1.7 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -34,22 +34,6 @@
*/
#define _CATEGORY_TYPE _NumericLocale
-static __inline void
-_PREFIX(build_cache)(struct _locale_cache_t * __restrict cache,
- _NumericLocale * __restrict data)
-{
- struct lconv *ldata;
-
- _DIAGASSERT(cache != NULL);
- _DIAGASSERT(cache->ldata != NULL);
- _DIAGASSERT(data != NULL);
-
- ldata = cache->ldata;
- ldata->decimal_point = __UNCONST(data->decimal_point);
- ldata->thousands_sep = __UNCONST(data->thousands_sep);
- ldata->grouping = __UNCONST(data->grouping);
-}
-
/* ARGSUSED */
static __inline void
_PREFIX(update_global)(_NumericLocale *data)
Index: src/lib/libc/locale/nb_lc_template.h
diff -u src/lib/libc/locale/nb_lc_template.h:1.7 src/lib/libc/locale/nb_lc_template.h:1.8
--- src/lib/libc/locale/nb_lc_template.h:1.7 Sun Aug 18 20:03:48 2013
+++ src/lib/libc/locale/nb_lc_template.h Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: nb_lc_template.h,v 1.7 2013/08/18 20:03:48 joerg Exp $ */
+/* $NetBSD: nb_lc_template.h,v 1.8 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)1999, 2008 Citrus Project,
@@ -234,7 +234,6 @@ _PREFIX(setlocale)(const char * __restri
return NULL;
locale->part_name[(size_t)_CATEGORY_ID] = loaded_name;
locale->part_impl[(size_t)_CATEGORY_ID] = loaded_impl;
- _PREFIX(build_cache)(locale->cache, loaded_impl);
if (locale == &_lc_global_locale)
_PREFIX(update_global)(loaded_impl);
}
Index: src/lib/libc/locale/nb_lc_time_misc.h
diff -u src/lib/libc/locale/nb_lc_time_misc.h:1.7 src/lib/libc/locale/nb_lc_time_misc.h:1.8
--- src/lib/libc/locale/nb_lc_time_misc.h:1.7 Tue Aug 20 19:58:30 2013
+++ src/lib/libc/locale/nb_lc_time_misc.h Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: nb_lc_time_misc.h,v 1.7 2013/08/20 19:58:30 joerg Exp $ */
+/* $NetBSD: nb_lc_time_misc.h,v 1.8 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -40,15 +40,6 @@
#define MON_IDX(idx) ((size_t)idx - (size_t)MON_1)
#define AM_PM_IDX(idx) ((size_t)idx - (size_t)AM_STR)
-static __inline void
-/*ARGSUSED*/
-_PREFIX(build_cache)(struct _locale_cache_t * __restrict cache,
- _TimeLocale * __restrict data)
-{
- _DIAGASSERT(cache != NULL);
- _DIAGASSERT(data != NULL);
-}
-
/* ARGSUSED */
static __inline void
_PREFIX(update_global)(_TimeLocale *data)
Index: src/lib/libc/locale/nb_lc_template_decl.h
diff -u src/lib/libc/locale/nb_lc_template_decl.h:1.3 src/lib/libc/locale/nb_lc_template_decl.h:1.4
--- src/lib/libc/locale/nb_lc_template_decl.h:1.3 Sun Aug 18 20:03:48 2013
+++ src/lib/libc/locale/nb_lc_template_decl.h Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: nb_lc_template_decl.h,v 1.3 2013/08/18 20:03:48 joerg Exp $ */
+/* $NetBSD: nb_lc_template_decl.h,v 1.4 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -36,10 +36,6 @@ _PREFIX(create_impl)(const char * __rest
const char * __restrict, _CATEGORY_TYPE ** __restrict);
static __inline void
-_PREFIX(build_cache)(struct _locale_cache_t * __restrict,
- _CATEGORY_TYPE * __restrict);
-
-static __inline void
_PREFIX(update_global)(_CATEGORY_TYPE *);
#endif /*_NB_LC_TEMPLATE_DECL_H_*/
Index: src/lib/libc/locale/newlocale.c
diff -u src/lib/libc/locale/newlocale.c:1.2 src/lib/libc/locale/newlocale.c:1.3
--- src/lib/libc/locale/newlocale.c:1.2 Fri May 17 12:55:57 2013
+++ src/lib/libc/locale/newlocale.c Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: newlocale.c,v 1.2 2013/05/17 12:55:57 joerg Exp $ */
+/* $NetBSD: newlocale.c,v 1.3 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008, 2011 Citrus Project,
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: newlocale.c,v 1.2 2013/05/17 12:55:57 joerg Exp $");
+__RCSID("$NetBSD: newlocale.c,v 1.3 2013/09/13 13:13:32 joerg Exp $");
#include "namespace.h"
#include <assert.h>
@@ -97,5 +97,9 @@ newlocale(int mask, const char *name, lo
}
}
}
+ if (_setlocale_cache(dst, NULL)) {
+ free(dst);
+ return NULL;
+ }
return (locale_t)dst;
}
Index: src/lib/libc/locale/setlocale.c
diff -u src/lib/libc/locale/setlocale.c:1.63 src/lib/libc/locale/setlocale.c:1.64
--- src/lib/libc/locale/setlocale.c:1.63 Fri May 17 12:55:57 2013
+++ src/lib/libc/locale/setlocale.c Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: setlocale.c,v 1.63 2013/05/17 12:55:57 joerg Exp $ */
+/* $NetBSD: setlocale.c,v 1.64 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -28,10 +28,11 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: setlocale.c,v 1.63 2013/05/17 12:55:57 joerg Exp $");
+__RCSID("$NetBSD: setlocale.c,v 1.64 2013/09/13 13:13:32 joerg Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
+#include <sys/localedef.h>
#include <locale.h>
#include <limits.h>
#include <paths.h>
@@ -53,6 +54,76 @@ static _locale_set_t all_categories[_LC_
[LC_MESSAGES] = &_citrus_LC_MESSAGES_setlocale,
};
+/* XXX Consider locking the list. Race condition leaks memory. */
+static SLIST_HEAD(, _locale_cache_t) caches = {
+ __UNCONST(&_C_cache)
+};
+
+int
+_setlocale_cache(locale_t loc, struct _locale_cache_t *cache)
+{
+ const char *monetary_name = loc->part_name[LC_MONETARY];
+ const char *numeric_name = loc->part_name[LC_NUMERIC];
+ _NumericLocale *numeric = loc->part_impl[LC_NUMERIC];
+ _MonetaryLocale *monetary = loc->part_impl[LC_MONETARY];
+ struct lconv *ldata;
+
+ struct _locale_cache_t *old_cache;
+
+ SLIST_FOREACH(old_cache, &caches, cache_link) {
+ if (monetary_name != old_cache->monetary_name &&
+ strcmp(monetary_name, old_cache->monetary_name) != 0)
+ continue;
+ if (numeric_name != old_cache->numeric_name &&
+ strcmp(numeric_name, old_cache->numeric_name) != 0)
+ continue;
+ loc->cache = old_cache;
+ free(cache);
+ return 0;
+ }
+
+ if (cache == NULL) {
+ cache = malloc(sizeof(*cache));
+ if (cache == NULL)
+ return -1;
+ }
+
+ cache->monetary_name = monetary_name;
+ cache->numeric_name = numeric_name;
+ ldata = &cache->ldata;
+
+ ldata->decimal_point = __UNCONST(numeric->decimal_point);
+ ldata->thousands_sep = __UNCONST(numeric->thousands_sep);
+ ldata->grouping = __UNCONST(numeric->grouping);
+
+ ldata->int_curr_symbol = __UNCONST(monetary->int_curr_symbol);
+ ldata->currency_symbol = __UNCONST(monetary->currency_symbol);
+ ldata->mon_decimal_point = __UNCONST(monetary->mon_decimal_point);
+ ldata->mon_thousands_sep = __UNCONST(monetary->mon_thousands_sep);
+ ldata->mon_grouping = __UNCONST(monetary->mon_grouping);
+ ldata->positive_sign = __UNCONST(monetary->positive_sign);
+ ldata->negative_sign = __UNCONST(monetary->negative_sign);
+
+ ldata->int_frac_digits = monetary->int_frac_digits;
+ ldata->frac_digits = monetary->frac_digits;
+ ldata->p_cs_precedes = monetary->p_cs_precedes;
+ ldata->p_sep_by_space = monetary->p_sep_by_space;
+ ldata->n_cs_precedes = monetary->n_cs_precedes;
+ ldata->n_sep_by_space = monetary->n_sep_by_space;
+ ldata->p_sign_posn = monetary->p_sign_posn;
+ ldata->n_sign_posn = monetary->n_sign_posn;
+ ldata->int_p_cs_precedes = monetary->int_p_cs_precedes;
+ ldata->int_n_cs_precedes = monetary->int_n_cs_precedes;
+ ldata->int_p_sep_by_space = monetary-> int_p_sep_by_space;
+ ldata->int_n_sep_by_space = monetary->int_n_sep_by_space;
+ ldata->int_p_sign_posn = monetary->int_p_sign_posn;
+ ldata->int_n_sign_posn = monetary->int_n_sign_posn;
+ SLIST_INSERT_HEAD(&caches, cache, cache_link);
+
+ loc->cache = cache;
+ return 0;
+}
+
_locale_set_t
_find_category(int category)
{
@@ -96,13 +167,20 @@ char *
__setlocale(int category, const char *name)
{
_locale_set_t sl;
- struct _locale *impl;
+ locale_t loc;
+ struct _locale_cache_t *cache;
+ const char *result;
sl = _find_category(category);
if (sl == NULL)
return NULL;
- impl = _current_locale();
- return __UNCONST((*sl)(name, impl));
+ cache = malloc(sizeof(*cache));
+ if (cache == NULL)
+ return NULL;
+ loc = _current_locale();
+ result = (*sl)(name, loc);
+ _setlocale_cache(loc, cache);
+ return __UNCONST(result);
}
char *
Index: src/lib/libc/locale/setlocale_local.h
diff -u src/lib/libc/locale/setlocale_local.h:1.14 src/lib/libc/locale/setlocale_local.h:1.15
--- src/lib/libc/locale/setlocale_local.h:1.14 Tue Aug 20 19:58:30 2013
+++ src/lib/libc/locale/setlocale_local.h Fri Sep 13 13:13:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: setlocale_local.h,v 1.14 2013/08/20 19:58:30 joerg Exp $ */
+/* $NetBSD: setlocale_local.h,v 1.15 2013/09/13 13:13:32 joerg Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@@ -29,6 +29,9 @@
#ifndef _SETLOCALE_LOCAL_H_
#define _SETLOCALE_LOCAL_H_
+#include <sys/queue.h>
+#include <locale.h>
+
#include "ctype_local.h"
#define _LOCALENAME_LEN_MAX 33
@@ -42,11 +45,14 @@ extern const char *_PathLocale;
typedef void *_locale_part_t;
struct _locale_cache_t {
- struct lconv *ldata;
+ SLIST_ENTRY(_locale_cache_t) cache_link;
+ const char *monetary_name;
+ const char *numeric_name;
+ struct lconv ldata;
};
struct _locale {
- struct _locale_cache_t *cache;
+ const struct _locale_cache_t *cache;
char query[_LOCALENAME_LEN_MAX * (_LC_LAST - 1)];
const char *part_name[_LC_LAST];
_locale_part_t part_impl[_LC_LAST];
@@ -74,22 +80,19 @@ const char *_citrus_LC_TIME_setlocale(
const char * __restrict, struct _locale * __restrict);
const char *_citrus_LC_MESSAGES_setlocale(
const char * __restrict, struct _locale * __restrict);
+
+int _setlocale_cache(locale_t, struct _locale_cache_t *);
__END_DECLS
#ifdef _LIBC
extern __dso_protected struct _locale _lc_global_locale;
+extern __dso_hidden const struct _locale_cache_t _C_cache;
static __inline struct _locale *
_current_locale(void)
{
return &_lc_global_locale;
}
-
-static __inline struct _locale_cache_t *
-_current_cache(void)
-{
- return _lc_global_locale.cache;
-}
#endif
extern size_t __mb_len_max_runtime;