summaryrefslogtreecommitdiffstats
path: root/lib/libc/locale/lnumeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/locale/lnumeric.c')
-rw-r--r--lib/libc/locale/lnumeric.c68
1 files changed, 51 insertions, 17 deletions
diff --git a/lib/libc/locale/lnumeric.c b/lib/libc/locale/lnumeric.c
index d4ed04f..a2468f4 100644
--- a/lib/libc/locale/lnumeric.c
+++ b/lib/libc/locale/lnumeric.c
@@ -2,6 +2,11 @@
* Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
*
+ * 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:
@@ -32,7 +37,6 @@ __FBSDID("$FreeBSD$");
#include "ldpart.h"
#include "lnumeric.h"
-extern int __nlocale_changed;
extern const char *__fix_locale_grouping_str(const char *);
#define LCNUMERIC_SIZE (sizeof(struct lc_numeric_T) / sizeof(char *))
@@ -45,37 +49,67 @@ static const struct lc_numeric_T _C_numeric_locale = {
numempty /* grouping */
};
-static struct lc_numeric_T _numeric_locale;
-static int _numeric_using_locale;
-static char *_numeric_locale_buf;
+static void
+destruct_numeric(void *v)
+{
+ struct xlocale_numeric *l = v;
+ if (l->buffer)
+ free(l->buffer);
+ free(l);
+}
+
+struct xlocale_numeric __xlocale_global_numeric;
-int
-__numeric_load_locale(const char *name)
+static int
+numeric_load_locale(struct xlocale_numeric *loc, int *using_locale, int *changed,
+ const char *name)
{
int ret;
+ struct lc_numeric_T *l = &loc->locale;
- ret = __part_load_locale(name, &_numeric_using_locale,
- &_numeric_locale_buf, "LC_NUMERIC",
+ ret = __part_load_locale(name, using_locale,
+ &loc->buffer, "LC_NUMERIC",
LCNUMERIC_SIZE, LCNUMERIC_SIZE,
- (const char **)&_numeric_locale);
+ (const char**)l);
if (ret != _LDP_ERROR)
- __nlocale_changed = 1;
+ *changed= 1;
if (ret == _LDP_LOADED) {
/* Can't be empty according to C99 */
- if (*_numeric_locale.decimal_point == '\0')
- _numeric_locale.decimal_point =
+ if (*l->decimal_point == '\0')
+ l->decimal_point =
_C_numeric_locale.decimal_point;
- _numeric_locale.grouping =
- __fix_locale_grouping_str(_numeric_locale.grouping);
+ l->grouping =
+ __fix_locale_grouping_str(l->grouping);
}
return (ret);
}
+int
+__numeric_load_locale(const char *name)
+{
+ return numeric_load_locale(&__xlocale_global_numeric,
+ &__xlocale_global_locale.using_numeric_locale,
+ &__xlocale_global_locale.numeric_locale_changed, name);
+}
+void *
+__numeric_load(const char *name, locale_t l)
+{
+ struct xlocale_numeric *new = calloc(sizeof(struct xlocale_numeric), 1);
+ new->header.header.destructor = destruct_numeric;
+ if (numeric_load_locale(new, &l->using_numeric_locale,
+ &l->numeric_locale_changed, name) == _LDP_ERROR)
+ {
+ xlocale_release(new);
+ return NULL;
+ }
+ return new;
+}
+
struct lc_numeric_T *
-__get_current_numeric_locale(void)
+__get_current_numeric_locale(locale_t loc)
{
- return (_numeric_using_locale
- ? &_numeric_locale
+ return (loc->using_numeric_locale
+ ? &((struct xlocale_numeric *)loc->components[XLC_NUMERIC])->locale
: (struct lc_numeric_T *)&_C_numeric_locale);
}
OpenPOWER on IntegriCloud