X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/1f2f436a38f7ae2d39a943ad2898d8fed4ed2e58..15de9d6b4ab2de27ae24b13b7b6c4d55fffe4aef:/locale/FreeBSD/localeconv.c?ds=inline diff --git a/locale/FreeBSD/localeconv.c b/locale/FreeBSD/localeconv.c index 919fd02..bad6ae8 100644 --- a/locale/FreeBSD/localeconv.c +++ b/locale/FreeBSD/localeconv.c @@ -34,11 +34,71 @@ static char sccsid[] = "@(#)localeconv.c 8.1 (Berkeley) 6/4/93"; #include __FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.14 2007/12/12 07:43:23 phantom Exp $"); +#include "xlocale_private.h" + +#include #include #include "lmonetary.h" #include "lnumeric.h" +#ifdef __APPLE_PR3417676_HACK__ +/*------------------------------------------------------------------------ + * PR-3417676: We need to provide a way to force "C" locale style number + * formatting independent of the locale setting. We provide private + * routines to get and set a flag that tells localeconv() to either return + * a "C" struct lconv, or the one dependent on the actual locale. + *------------------------------------------------------------------------*/ +static char empty[] = ""; +static char numempty[] = { CHAR_MAX, '\0' }; + +/* + * Default (C) locale conversion. + */ +static struct lconv _C_lconv = { + ".", /* decimal_point */ + empty, /* thousands_sep */ + numempty, /* grouping */ + empty, /* int_curr_symbol */ + empty, /* currency_symbol */ + empty, /* mon_decimal_point */ + empty, /* mon_thousands_sep */ + numempty, /* mon_grouping */ + empty, /* positive_sign */ + empty, /* negative_sign */ + CHAR_MAX, /* int_frac_digits */ + CHAR_MAX, /* frac_digits */ + CHAR_MAX, /* p_cs_precedes */ + CHAR_MAX, /* p_sep_by_space */ + CHAR_MAX, /* n_cs_precedes */ + CHAR_MAX, /* n_sep_by_space */ + CHAR_MAX, /* p_sign_posn */ + CHAR_MAX, /* n_sign_posn */ + CHAR_MAX, /* int_p_cs_precedes */ + CHAR_MAX, /* int_n_cs_precedes */ + CHAR_MAX, /* int_p_sep_by_space */ + CHAR_MAX, /* int_n_sep_by_space */ + CHAR_MAX, /* int_p_sign_posn */ + CHAR_MAX, /* int_n_sign_posn */ +}; +static int _onlyClocaleconv = 0; + +int +__getonlyClocaleconv(void) +{ + return _onlyClocaleconv; +} + +int +__setonlyClocaleconv(int val) +{ + int prev = _onlyClocaleconv; + + _onlyClocaleconv = val; + return prev; +} +#endif /* __APPLE_PR3417676_HACK__ */ + /* * The localeconv() function constructs a struct lconv from the current * monetary and numeric locales. @@ -48,25 +108,26 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.14 2007/12/12 07:43:23 * lconv structure are computed only when the monetary or numeric * locale has been changed. */ -int __mlocale_changed = 1; -int __nlocale_changed = 1; /* * Return the current locale conversion. */ struct lconv * -localeconv() +localeconv_l(locale_t loc) { - static struct lconv ret; + NORMALIZE_LOCALE(loc); - if (__mlocale_changed) { + if (loc->__mlocale_changed) { + XL_LOCK(loc); + if (loc->__mlocale_changed) { /* LC_MONETARY part */ struct lc_monetary_T * mptr; + struct lconv *lc = &loc->__lc_localeconv; -#define M_ASSIGN_STR(NAME) (ret.NAME = (char*)mptr->NAME) -#define M_ASSIGN_CHAR(NAME) (ret.NAME = mptr->NAME[0]) +#define M_ASSIGN_STR(NAME) (lc->NAME = (char*)mptr->NAME) +#define M_ASSIGN_CHAR(NAME) (lc->NAME = mptr->NAME[0]) - mptr = __get_current_monetary_locale(); + mptr = __get_current_monetary_locale(loc); M_ASSIGN_STR(int_curr_symbol); M_ASSIGN_STR(currency_symbol); M_ASSIGN_STR(mon_decimal_point); @@ -88,21 +149,45 @@ localeconv() M_ASSIGN_CHAR(int_n_sep_by_space); M_ASSIGN_CHAR(int_p_sign_posn); M_ASSIGN_CHAR(int_n_sign_posn); - __mlocale_changed = 0; + loc->__mlocale_changed = 0; + } + XL_UNLOCK(loc); } - if (__nlocale_changed) { + if (loc->__nlocale_changed) { + XL_LOCK(loc); + if (loc->__nlocale_changed) { /* LC_NUMERIC part */ struct lc_numeric_T * nptr; + struct lconv *lc = &loc->__lc_localeconv; -#define N_ASSIGN_STR(NAME) (ret.NAME = (char*)nptr->NAME) +#define N_ASSIGN_STR(NAME) (lc->NAME = (char*)nptr->NAME) - nptr = __get_current_numeric_locale(); + nptr = __get_current_numeric_locale(loc); N_ASSIGN_STR(decimal_point); N_ASSIGN_STR(thousands_sep); N_ASSIGN_STR(grouping); - __nlocale_changed = 0; + loc->__nlocale_changed = 0; + } + XL_UNLOCK(loc); } - return (&ret); + return &loc->__lc_localeconv; +} + +/* + * Return the current locale conversion. + */ +struct lconv * +localeconv() +{ +#ifdef __APPLE_PR3417676_HACK__ + /*-------------------------------------------------------------------- + * If _onlyClocaleconv is non-zero, just return __lconv, which is a "C" + * struct lconv *. Otherwise, do the normal thing. + *--------------------------------------------------------------------*/ + if (_onlyClocaleconv) + return &_C_lconv; +#endif /* __APPLE_PR3417676_HACK__ */ + return localeconv_l(__current_locale()); }