Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | --- lnumeric.c.orig 2004-11-25 11:38:17.000000000 -0800 +++ lnumeric.c 2005-03-16 23:06:13.000000000 -0800 @@ -27,67 +27,103 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/lib/libc/locale/lnumeric.c,v 1.16 2003/06/26 10:46:16 phantom Exp $"); +#include "xlocale_private.h" + #include <limits.h> +#include <string.h> #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 */ |