Print this page
2964 need POSIX 2008 locale object support

*** 1,10 **** --- 1,15 ---- /* * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
*** 29,39 **** #include <limits.h> #include "ldpart.h" #include "lnumeric.h" #include "../i18n/_locale.h" - extern int __nlocale_changed; extern const char *__fix_locale_grouping_str(const char *); #define LCNUMERIC_SIZE (sizeof (struct lc_numeric_T) / sizeof (char *)) static char numempty[] = { CHAR_MAX, '\0' }; --- 34,43 ----
*** 42,85 **** ".", /* decimal_point */ "", /* thousands_sep */ numempty /* grouping */ }; ! static struct lc_numeric_T _numeric_locale; ! static int _numeric_using_locale; ! static char *_numeric_locale_buf; ! ! int ! __numeric_load_locale(const char *name) { ! const struct lc_numeric_T *leg = &_C_numeric_locale; int ret; ! ret = __part_load_locale(name, &_numeric_using_locale, ! &_numeric_locale_buf, "LC_NUMERIC", LCNUMERIC_SIZE, LCNUMERIC_SIZE, ! (const char **)&_numeric_locale); ! if (ret == _LDP_ERROR) ! return (_LDP_ERROR); - __nlocale_changed = 1; if (ret == _LDP_LOADED) { /* Can't be empty according to C99 */ ! if (*_numeric_locale.decimal_point == '\0') ! _numeric_locale.decimal_point = _C_numeric_locale.decimal_point; ! _numeric_locale.grouping = ! __fix_locale_grouping_str(_numeric_locale.grouping); ! leg = (const struct lc_numeric_T *)&_numeric_locale; } /* This is Solaris legacy, required for ABI compatability */ ! _numeric[0] = *leg->decimal_point; ! _numeric[1] = *leg->grouping; return (ret); } struct lc_numeric_T * ! __get_current_numeric_locale(void) { ! return (_numeric_using_locale ? &_numeric_locale : ! (struct lc_numeric_T *)&_C_numeric_locale); } --- 46,127 ---- ".", /* decimal_point */ "", /* thousands_sep */ numempty /* grouping */ }; ! static void ! destruct_numeric(void *v) { ! struct xlocale_numeric *l = v; ! ! if (l->buffer != NULL) ! free(l->buffer); + free(l); + } + + struct xlocale_numeric __xlocale_global_numeric; + + static int + numeric_load_locale(struct xlocale_numeric *loc, int *using_locale, + int *changed, const char *name) + { + int leg; int ret; + struct lc_numeric_T *l = &loc->locale; ! ret = __part_load_locale(name, using_locale, ! &loc->buffer, "LC_NUMERIC", ! LCNUMERIC_SIZE, LCNUMERIC_SIZE, ! (const char **)l); ! if (ret != _LDP_ERROR) ! *changed = 1; if (ret == _LDP_LOADED) { /* Can't be empty according to C99 */ ! if (*l->decimal_point == '\0') ! l->decimal_point = _C_numeric_locale.decimal_point; ! l->grouping = ! __fix_locale_grouping_str(l->grouping); ! // XXX leg = (const struct lc_numeric_T *)&_numeric_locale; } /* This is Solaris legacy, required for ABI compatability */ ! // _numeric[0] = *leg->decimal_point; ! // _numeric[1] = *leg->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; + + new = calloc(sizeof(struct xlocale_numeric), 1); + if (new == NULL) + return (NULL); + + 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(locale_t loc) { ! return (loc->using_numeric_locale ! ? &((struct xlocale_numeric *)loc->components[XLC_NUMERIC])->locale ! : (struct lc_numeric_T *)&_C_numeric_locale); }