Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Approved by: TBD

@@ -1,6 +1,7 @@
 /*
+ * Copyright 2014 Garrett D'Amore.
  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

@@ -25,61 +26,61 @@
  * SUCH DAMAGE.
  */
 
 #include "lint.h"
 #include <limits.h>
+#include <errno.h>
 #include "ldpart.h"
 #include "lnumeric.h"
-#include "../i18n/_locale.h"
+#include "localeimpl.h"
 
-extern int __nlocale_changed;
 extern const char *__fix_locale_grouping_str(const char *);
 
-#define LCNUMERIC_SIZE (sizeof (struct lc_numeric_T) / sizeof (char *))
+#define LCNUMERIC_SIZE (sizeof (struct lc_numeric) / sizeof (char *))
 
 static char     numempty[] = { CHAR_MAX, '\0' };
 
-static const struct lc_numeric_T _C_numeric_locale = {
+struct lc_numeric lc_numeric_posix = {
         ".",            /* decimal_point */
         "",             /* thousands_sep */
         numempty        /* grouping */
 };
 
-static struct lc_numeric_T _numeric_locale;
-static int      _numeric_using_locale;
-static char     *_numeric_locale_buf;
+struct locdata __posix_numeric_locdata = {
+        .l_lname = "C",
+        .l_refcnt = (uint32_t)-1,
+        .l_data = { &lc_numeric_posix }
+};
 
-int
-__numeric_load_locale(const char *name)
-{
-        const struct lc_numeric_T *leg = &_C_numeric_locale;
 
+/*
+ * Return the locale's numeric locdata structure, places a hold on it,
+ * which the caller must release.
+ */
+struct locdata *
+__lc_numeric_load(const char *name)
+{
+        struct locdata *ldata;
+        struct lc_numeric *lnum;
         int ret;
 
-        ret = __part_load_locale(name, &_numeric_using_locale,
-            &_numeric_locale_buf, "LC_NUMERIC", LCNUMERIC_SIZE, LCNUMERIC_SIZE,
-            (const char **)&_numeric_locale);
-        if (ret == _LDP_ERROR)
-                return (_LDP_ERROR);
+        if ((ldata = __locdata_alloc(name, sizeof (*lnum))) == NULL) {
+                errno = EINVAL;
+                return (NULL);
+        }
+        lnum = ldata->l_data[0];
 
-        __nlocale_changed = 1;
-        if (ret == _LDP_LOADED) {
-                /* Can't be empty according to C99 */
-                if (*_numeric_locale.decimal_point == '\0')
-                        _numeric_locale.decimal_point =
-                            _C_numeric_locale.decimal_point;
-                _numeric_locale.grouping =
-                    __fix_locale_grouping_str(_numeric_locale.grouping);
-                leg = (const struct lc_numeric_T *)&_numeric_locale;
+        ret = __part_load_locale(name, (char **)&ldata->l_data[1],
+            "LC_NUMERIC", LCNUMERIC_SIZE, LCNUMERIC_SIZE, (const char **)lnum);
+
+        if (ret != _LDP_LOADED) {
+                __locdata_release(ldata);
+                return (NULL);
         }
-        /* This is Solaris legacy, required for ABI compatability */
-        _numeric[0] = *leg->decimal_point;
-        _numeric[1] = *leg->grouping;
-        return (ret);
-}
 
-struct lc_numeric_T *
-__get_current_numeric_locale(void)
-{
-        return (_numeric_using_locale ? &_numeric_locale :
-            (struct lc_numeric_T *)&_C_numeric_locale);
+        /* Can't be empty according to C99 */
+        if (*lnum->decimal_point == '\0')
+                lnum->decimal_point = lc_numeric_posix.decimal_point;
+        lnum->grouping = __fix_locale_grouping_str(lnum->grouping);
+
+        return (ldata);
 }