X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..15de9d6b4ab2de27ae24b13b7b6c4d55fffe4aef:/locale/FreeBSD/lnumeric.c diff --git a/locale/FreeBSD/lnumeric.c b/locale/FreeBSD/lnumeric.c index 8dcdaa1..adfa25b 100644 --- a/locale/FreeBSD/lnumeric.c +++ b/locale/FreeBSD/lnumeric.c @@ -25,68 +25,105 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/lnumeric.c,v 1.14 2003/03/20 08:05:20 ache Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/locale/lnumeric.c,v 1.16 2003/06/26 10:46:16 phantom Exp $"); + +#include "xlocale_private.h" #include -#include "lnumeric.h" +#include + #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 *)) -static char numempty[] = { CHAR_MAX, '\0' }; - static const struct lc_numeric_T _C_numeric_locale = { ".", /* decimal_point */ "", /* thousands_sep */ - numempty /* grouping */ + "" /* grouping [C99 7.11.2.1]*/ }; -static struct lc_numeric_T _numeric_locale; -static int _numeric_using_locale; -static char *_numeric_locale_buf; - -int -__numeric_load_locale(const char *name) +__private_extern__ int +__numeric_load_locale(const char *name, locale_t loc) { int ret; + struct __xlocale_st_numeric *xp; + static struct __xlocale_st_numeric *cache = NULL; + + /* 'name' must be already checked. */ + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + if (!loc->_numeric_using_locale) + return (_LDP_CACHE); + loc->_numeric_using_locale = 0; + XL_RELEASE(loc->__lc_numeric); + loc->__lc_numeric = NULL; + loc->__nlocale_changed = 1; + return (_LDP_CACHE); + } + + if (loc->_numeric_using_locale && strcmp(name, loc->__lc_numeric->_numeric_locale_buf) == 0) + return (_LDP_CACHE); + /* + * If the locale name is the same as our cache, use the cache. + */ + if (cache && cache->_numeric_locale_buf && strcmp(name, cache->_numeric_locale_buf) == 0) { + loc->_numeric_using_locale = 1; + XL_RELEASE(loc->__lc_numeric); + loc->__lc_numeric = cache; + XL_RETAIN(loc->__lc_numeric); + loc->__nlocale_changed = 1; + return (_LDP_CACHE); + } + if ((xp = (struct __xlocale_st_numeric *)malloc(sizeof(*xp))) == NULL) + return _LDP_ERROR; + xp->__refcount = 1; + xp->__free_extra = (__free_extra_t)__ldpart_free_extra; + xp->_numeric_locale_buf = NULL; - ret = __part_load_locale(name, &_numeric_using_locale, - _numeric_locale_buf, "LC_NUMERIC", + ret = __part_load_locale(name, &loc->_numeric_using_locale, + &xp->_numeric_locale_buf, "LC_NUMERIC", LCNUMERIC_SIZE, LCNUMERIC_SIZE, - (const char **)&_numeric_locale); + (const char **)&xp->_numeric_locale); if (ret != _LDP_ERROR) - __nlocale_changed = 1; + loc->__nlocale_changed = 1; + else + free(xp); if (ret == _LDP_LOADED) { /* Can't be empty according to C99 */ - if (*_numeric_locale.decimal_point == '\0') - _numeric_locale.decimal_point = + if (*xp->_numeric_locale.decimal_point == '\0') + xp->_numeric_locale.decimal_point = _C_numeric_locale.decimal_point; - _numeric_locale.grouping = - __fix_locale_grouping_str(_numeric_locale.grouping); + xp->_numeric_locale.grouping = + __fix_locale_grouping_str(xp->_numeric_locale.grouping); + XL_RELEASE(loc->__lc_numeric); + loc->__lc_numeric = xp; + XL_RELEASE(cache); + cache = xp; + XL_RETAIN(cache); } return (ret); } -struct lc_numeric_T * -__get_current_numeric_locale(void) +__private_extern__ struct lc_numeric_T * +__get_current_numeric_locale(locale_t loc) { - return (_numeric_using_locale - ? &_numeric_locale + return (loc->_numeric_using_locale + ? &loc->__lc_numeric->_numeric_locale : (struct lc_numeric_T *)&_C_numeric_locale); } #ifdef LOCALE_DEBUG void numericdebug(void) { +locale_t loc = __current_locale(); printf( "decimal_point = %s\n" "thousands_sep = %s\n" "grouping = %s\n", - _numeric_locale.decimal_point, - _numeric_locale.thousands_sep, - _numeric_locale.grouping + loc->__lc_numeric->_numeric_locale.decimal_point, + loc->__lc_numeric->_numeric_locale.thousands_sep, + loc->__lc_numeric->_numeric_locale.grouping ); } #endif /* LOCALE_DEBUG */