Remove the static/global variables from localeconv(3).

- store the cached values inside struct _locale_t (like FreeBSD)

- use flags (member of locale_t) to track changes in lc_monetary or
  lc_numeric. Note that currently these categories support only C
  locale, so there are no code that change them (as for
  __mlocale_changed and __nlocale_changed before).

-- 
Sebastien Marie

Index: b/lib/libc/locale/localeconv.c
===================================================================
--- a/lib/libc/locale/localeconv.c      2015-07-08 11:56:51.883919979 +0200
+++ b/lib/libc/locale/localeconv.c      2015-07-08 14:49:26.182312619 +0200
@@ -18,8 +18,13 @@
  * lconv structure are computed only when the monetary or numeric
  * locale has been changed.
  */
-int __mlocale_changed = 1;
-int __nlocale_changed = 1;
+
+/* helpers */
+#define lconvcpy_monetary(_loc, _entry) \
+       (_loc->lconv_cached._entry = _loc->lc_monetary->_entry)
+
+#define lconvcpy_numeric(_loc, _entry) \
+       (_loc->lconv_cached._entry = (char *)_loc->lc_numeric->_entry)
 
 /*
  * Return the current locale conversion.
@@ -27,42 +32,43 @@
 struct lconv *
 localeconv(void)
 {
-    static struct lconv ret;
-    locale_t loc = _current_locale();
+       locale_t loc = _current_locale();
 
-    if (__mlocale_changed) {
        /* LC_MONETARY */
-       ret.int_curr_symbol     = loc->lc_monetary->int_curr_symbol;
-       ret.currency_symbol     = loc->lc_monetary->currency_symbol;
-       ret.mon_decimal_point   = loc->lc_monetary->mon_decimal_point;
-       ret.mon_thousands_sep   = loc->lc_monetary->mon_thousands_sep;
-       ret.mon_grouping        = loc->lc_monetary->mon_grouping;
-       ret.positive_sign       = loc->lc_monetary->positive_sign;
-       ret.negative_sign       = loc->lc_monetary->negative_sign;
-       ret.int_frac_digits     = loc->lc_monetary->int_frac_digits;
-       ret.frac_digits         = loc->lc_monetary->frac_digits;
-       ret.p_cs_precedes       = loc->lc_monetary->p_cs_precedes;
-       ret.p_sep_by_space      = loc->lc_monetary->p_sep_by_space;
-       ret.n_cs_precedes       = loc->lc_monetary->n_cs_precedes;
-       ret.n_sep_by_space      = loc->lc_monetary->n_sep_by_space;
-       ret.p_sign_posn         = loc->lc_monetary->p_sign_posn;
-       ret.n_sign_posn         = loc->lc_monetary->n_sign_posn;
-       ret.int_p_cs_precedes   = loc->lc_monetary->int_p_cs_precedes;
-       ret.int_p_sep_by_space  = loc->lc_monetary->int_p_sep_by_space;
-       ret.int_n_cs_precedes   = loc->lc_monetary->int_n_cs_precedes;
-       ret.int_n_sep_by_space  = loc->lc_monetary->int_n_sep_by_space;
-       ret.int_p_sign_posn     = loc->lc_monetary->int_p_sign_posn;
-       ret.int_n_sign_posn     = loc->lc_monetary->int_n_sign_posn;
-       __mlocale_changed = 0;
-    }
+       if (loc->flags & XLOCALE_MONETARY_CHANGED) {
+               lconvcpy_monetary(loc, int_curr_symbol);
+               lconvcpy_monetary(loc, currency_symbol);
+               lconvcpy_monetary(loc, mon_decimal_point);
+               lconvcpy_monetary(loc, mon_thousands_sep);
+               lconvcpy_monetary(loc, mon_grouping);
+               lconvcpy_monetary(loc, positive_sign);
+               lconvcpy_monetary(loc, negative_sign);
+               lconvcpy_monetary(loc, int_frac_digits);
+               lconvcpy_monetary(loc, frac_digits);
+               lconvcpy_monetary(loc, p_cs_precedes);
+               lconvcpy_monetary(loc, p_sep_by_space);
+               lconvcpy_monetary(loc, n_cs_precedes);
+               lconvcpy_monetary(loc, n_sep_by_space);
+               lconvcpy_monetary(loc, p_sign_posn);
+               lconvcpy_monetary(loc, n_sign_posn);
+               lconvcpy_monetary(loc, int_p_cs_precedes);
+               lconvcpy_monetary(loc, int_p_sep_by_space);
+               lconvcpy_monetary(loc, int_n_cs_precedes);
+               lconvcpy_monetary(loc, int_n_sep_by_space);
+               lconvcpy_monetary(loc, int_p_sign_posn);
+               lconvcpy_monetary(loc, int_n_sign_posn);
+
+               loc->flags &= ~XLOCALE_MONETARY_CHANGED;
+       }
 
-    if (__nlocale_changed) {
        /* LC_NUMERIC */
-       ret.decimal_point       = (char *) loc->lc_numeric->decimal_point;
-       ret.thousands_sep       = (char *) loc->lc_numeric->thousands_sep;
-       ret.grouping            = (char *) loc->lc_numeric->grouping;
-       __nlocale_changed = 0;
-    }
+       if (loc->flags & XLOCALE_NUMERIC_CHANGED) {
+               lconvcpy_numeric(loc, decimal_point);
+               lconvcpy_numeric(loc, thousands_sep);
+               lconvcpy_numeric(loc, grouping);
+
+               loc->flags &= ~XLOCALE_NUMERIC_CHANGED;
+       }
 
-    return (&ret);
+       return (&loc->lconv_cached);
 }
Index: b/lib/libc/locale/xlocale.c
===================================================================
--- a/lib/libc/locale/xlocale.c 2015-07-08 11:56:51.883919979 +0200
+++ b/lib/libc/locale/xlocale.c 2015-07-08 14:09:51.275324172 +0200
@@ -25,13 +25,14 @@
  * hold the global state
  */
 struct _locale_t _lc_global_locale = {
-       XLOCALE_INSTALLED,
+       XLOCALE_INSTALLED | XLOCALE_MONETARY_CHANGED | XLOCALE_NUMERIC_CHANGED,
        {"C", "C", "C", "C", "C", "C", "C"},
        &_DefaultRuneLocale,
        &_DefaultMessagesLocale,
        &_DefaultMonetaryLocale,
        &_DefaultNumericLocale,
-       &_DefaultTimeLocale
+       &_DefaultTimeLocale,
+       /* lconv_cached */
 };
 
 
Index: b/lib/libc/locale/xlocale_private.h
===================================================================
--- a/lib/libc/locale/xlocale_private.h 2015-07-08 11:56:51.883919979 +0200
+++ b/lib/libc/locale/xlocale_private.h 2015-07-08 13:57:41.989861830 +0200
@@ -31,9 +31,13 @@
        const _MonetaryLocale   *lc_monetary;
        const _NumericLocale    *lc_numeric;
        const _TimeLocale       *lc_time;
+
+       struct lconv            lconv_cached;
 };
 
 #define XLOCALE_INSTALLED    (1 << 0)
+#define XLOCALE_MONETARY_CHANGED (1 << 1)
+#define XLOCALE_NUMERIC_CHANGED  (1 << 2)
 
 #define xlocale_is_installed(flags) (flags & XLOCALE_INSTALLED)
 

Reply via email to