Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/localeconv.c
          +++ new/usr/src/lib/libc/port/locale/localeconv.c
   1    1  /*
        2 + * Copyright 2013 Garrett D'Amore <garrett@damore.org>
   2    3   * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   3    4   * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
   4    5   * Copyright (c) 1991, 1993
   5    6   *      The Regents of the University of California.  All rights reserved.
   6    7   *
   7    8   * Redistribution and use in source and binary forms, with or without
   8    9   * modification, are permitted provided that the following conditions
   9   10   * are met:
  10   11   * 1. Redistributions of source code must retain the above copyright
  11   12   *    notice, this list of conditions and the following disclaimer.
↓ open down ↓ 18 lines elided ↑ open up ↑
  30   31   */
  31   32  
  32   33  #ifndef _LCONV_C99
  33   34  #define _LCONV_C99      /* so we get all the extensions */
  34   35  #endif
  35   36  
  36   37  #include "lint.h"
  37   38  #include <locale.h>
  38   39  #include "lmonetary.h"
  39   40  #include "lnumeric.h"
       41 +#include "localeimpl.h"
  40   42  
  41   43  /*
  42      - * The localeconv() function constructs a struct lconv from the current
  43      - * monetary and numeric locales.
       44 + * Return the current locale conversion.
  44   45   *
       46 + * Note that XPG7 specifically states that localeconv's return value may
       47 + * be invalidated if the application calls setlocale() or uselocale() within
       48 + * the same thread.
       49 + *
  45   50   * Because localeconv() may be called many times (especially by library
  46   51   * routines like printf() & strtod()), the approprate members of the
  47   52   * lconv structure are computed only when the monetary or numeric
  48   53   * locale has been changed.
  49   54   */
  50      -int __mlocale_changed = 1;
  51      -int __nlocale_changed = 1;
  52      -
  53      -/*
  54      - * Return the current locale conversion.
  55      - */
  56   55  struct lconv *
  57   56  localeconv(void)
  58   57  {
  59      -        static struct lconv ret;
       58 +        struct lconv    *lconv;
       59 +        locale_t        loc;
       60 +        struct lc_monetary      *mptr;
       61 +        struct lc_numeric       *nptr;
  60   62  
  61      -        if (__mlocale_changed) {
  62      -                /* LC_MONETARY part */
  63      -                struct lc_monetary_T *mptr;
       63 +        loc = uselocale(NULL);
       64 +        lconv = &loc->lconv;
  64   65  
  65      -#define M_ASSIGN_STR(NAME) (ret.NAME = (char *)mptr->NAME)
  66      -#define M_ASSIGN_CHAR(NAME) (ret.NAME = mptr->NAME[0])
       66 +        if (loc->loaded[LC_MONETARY] == 0) {
       67 +                mptr = loc->locdata[LC_MONETARY]->l_data[0];
  67   68  
  68      -                mptr = __get_current_monetary_locale();
       69 +#define M_ASSIGN_STR(NAME) (lconv->NAME = (char *)mptr->NAME)
       70 +#define M_ASSIGN_CHAR(NAME) (lconv->NAME = mptr->NAME[0])
       71 +
  69   72                  M_ASSIGN_STR(int_curr_symbol);
  70   73                  M_ASSIGN_STR(currency_symbol);
  71   74                  M_ASSIGN_STR(mon_decimal_point);
  72   75                  M_ASSIGN_STR(mon_thousands_sep);
  73   76                  M_ASSIGN_STR(mon_grouping);
  74   77                  M_ASSIGN_STR(positive_sign);
  75   78                  M_ASSIGN_STR(negative_sign);
  76   79                  M_ASSIGN_CHAR(int_frac_digits);
  77   80                  M_ASSIGN_CHAR(frac_digits);
  78   81                  M_ASSIGN_CHAR(p_cs_precedes);
↓ open down ↓ 1 lines elided ↑ open up ↑
  80   83                  M_ASSIGN_CHAR(n_cs_precedes);
  81   84                  M_ASSIGN_CHAR(n_sep_by_space);
  82   85                  M_ASSIGN_CHAR(p_sign_posn);
  83   86                  M_ASSIGN_CHAR(n_sign_posn);
  84   87                  M_ASSIGN_CHAR(int_p_cs_precedes);
  85   88                  M_ASSIGN_CHAR(int_n_cs_precedes);
  86   89                  M_ASSIGN_CHAR(int_p_sep_by_space);
  87   90                  M_ASSIGN_CHAR(int_n_sep_by_space);
  88   91                  M_ASSIGN_CHAR(int_p_sign_posn);
  89   92                  M_ASSIGN_CHAR(int_n_sign_posn);
  90      -                __mlocale_changed = 0;
       93 +                loc->loaded[LC_MONETARY] = 1;
  91   94          }
  92   95  
  93      -        if (__nlocale_changed) {
  94      -                /* LC_NUMERIC part */
  95      -                struct lc_numeric_T *nptr;
       96 +        if (loc->loaded[LC_NUMERIC] == 0) {
       97 +                nptr = loc->locdata[LC_NUMERIC]->l_data[0];
  96   98  
  97      -#define N_ASSIGN_STR(NAME) (ret.NAME = (char *)nptr->NAME)
       99 +#define N_ASSIGN_STR(NAME) (lconv->NAME = (char *)nptr->NAME)
  98  100  
  99      -                nptr = __get_current_numeric_locale();
 100  101                  N_ASSIGN_STR(decimal_point);
 101  102                  N_ASSIGN_STR(thousands_sep);
 102  103                  N_ASSIGN_STR(grouping);
 103      -                __nlocale_changed = 0;
      104 +                loc->loaded[LC_NUMERIC] = 1;
 104  105          }
 105  106  
 106      -        return (&ret);
      107 +        return (lconv);
 107  108  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX