tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

duplocale/freelocale/newlocale support



Hi all,
attached is the remaining part for the explicit locale support.
This is with small changes from Takehiko Nozaki's patch.

Without going over the full libc source, this should bring us up to
POSIX2008 support with one exception. uselocale() and therefore thread
specific locales are not included. I am considering filling an issue
with Austin to declare that a separate extension. Adding thread specific
locales requires ABI breakage on most platforms and adds a non-trivial
performance penality e.g. to the ctype macros. I maintain that the gain
doesn't justify the cost.

Joerg
Index: include/locale.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/include/locale.h,v
retrieving revision 1.19
diff -u -p -r1.19 locale.h
--- include/locale.h    17 Apr 2013 20:40:13 -0000      1.19
+++ include/locale.h    21 Apr 2013 18:13:10 -0000
@@ -96,7 +96,17 @@ char *setlocale(int, const char *) __REN
 typedef struct _locale         *locale_t;
 #  define __LOCALE_T_DECLARED
 #  endif
+#define        LC_ALL_MASK             ((int)~0)
+#define        LC_COLLATE_MASK         ((int)(1 << LC_COLLATE))
+#define        LC_CTYPE_MASK           ((int)(1 << LC_CTYPE))
+#define        LC_MONETARY_MASK        ((int)(1 << LC_MONETARY))
+#define        LC_NUMERIC_MASK         ((int)(1 << LC_NUMERIC))
+#define        LC_TIME_MASK            ((int)(1 << LC_TIME))
+#define        LC_MESSAGES_MASK        ((int)(1 << LC_MESSAGES))
 struct lconv   *localeconv_l(locale_t);
+locale_t       duplocale(locale_t);
+void           freelocale(locale_t);
+locale_t       newlocale(int, const char *, locale_t);
 #endif
 __END_DECLS
 
Index: lib/libc/include/namespace.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/include/namespace.h,v
retrieving revision 1.165
diff -u -p -r1.165 namespace.h
--- lib/libc/include/namespace.h        21 Apr 2013 17:45:46 -0000      1.165
+++ lib/libc/include/namespace.h        21 Apr 2013 18:09:21 -0000
@@ -243,6 +243,7 @@
 #define dn_expand              _dn_expand
 #define dprintf_l              _dprintf_l
 #define drand48                        _drand48
+#define duplocale              _duplocale
 #define endfsent               _endfsent
 #define endgrent               _endgrent
 #define endhostent             _endhostent
@@ -290,6 +291,7 @@
 #define freenetconfigent       _freenetconfigent
 #define freeaddrinfo           _freeaddrinfo
 #define freeifaddrs            _freeifaddrs
+#define freelocale             _freelocale
 #define fscanf_l               _fscanf_l
 #define fstatvfs               _fstatvfs
 #define ftok                   _ftok
@@ -479,6 +481,7 @@
 #define nc_perror              _nc_perror
 #define nc_sperror             _nc_sperror
 #define nanosleep              _nanosleep
+#define newlocale              _newlocale
 #define nice                   _nice
 #if 0
 #define nlist                  _nlist
Index: lib/libc/locale/Makefile.inc
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/locale/Makefile.inc,v
retrieving revision 1.61
diff -u -p -r1.61 Makefile.inc
--- lib/libc/locale/Makefile.inc        14 Apr 2013 23:44:53 -0000      1.61
+++ lib/libc/locale/Makefile.inc        21 Apr 2013 18:32:37 -0000
@@ -6,8 +6,8 @@
 
 SRCS+= _def_messages.c _def_monetary.c _def_numeric.c _def_time.c \
        setlocale.c __mb_cur_max.c \
-       current_locale.c c_locale.c global_locale.c fix_grouping.c \
-       localeconv.c nl_langinfo.c \
+       current_locale.c c_locale.c duplocale.c global_locale.c fix_grouping.c \
+       freelocale.c localeconv.c newlocale.c nl_langinfo.c \
        generic_lc_all.c dummy_lc_collate.c \
        wcstol.c wcstoll.c wcstoimax.c wcstoul.c wcstoull.c wcstoumax.c \
        wcstod.c wcstof.c wcstold.c wcscoll.c wcsxfrm.c wcsftime.c
Index: lib/libc/locale/setlocale.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/locale/setlocale.c,v
retrieving revision 1.61
diff -u -p -r1.61 setlocale.c
--- lib/libc/locale/setlocale.c 14 Apr 2013 23:30:16 -0000      1.61
+++ lib/libc/locale/setlocale.c 22 Apr 2013 17:38:45 -0000
@@ -56,6 +56,16 @@ static _locale_set_t all_categories[_LC_
 _locale_set_t
 _find_category(int category)
 {
+       static int initialised;
+
+       if (!initialised) {
+               if (issetugid() || ((_PathLocale == NULL &&
+                   (_PathLocale = getenv("PATH_LOCALE")) == NULL) ||
+                   *_PathLocale == '\0'))
+                       _PathLocale = _PATH_LOCALE;
+               initialised = 1;
+       }
+
        if (category >= LC_ALL && category < _LC_LAST)
                return all_categories[category];
        return NULL;
@@ -91,10 +101,6 @@ __setlocale(int category, const char *na
        sl = _find_category(category);
        if (sl == NULL)
                return NULL;
-       if (issetugid() || ((_PathLocale == NULL &&
-           (_PathLocale = getenv("PATH_LOCALE")) == NULL) ||
-           *_PathLocale == '\0'))
-               _PathLocale = _PATH_LOCALE;
        impl = *_current_locale();
        return __UNCONST((*sl)(name, impl));
 }
Index: lib/libc/locale/duplocale.c
===================================================================
RCS file: lib/libc/locale/duplocale.c
diff -N lib/libc/locale/duplocale.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/libc/locale/duplocale.c 21 Apr 2013 18:18:23 -0000
@@ -0,0 +1,52 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c)2008, 2011 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD$");
+
+#include "namespace.h"
+
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#include "setlocale_local.h"
+
+__weak_alias(duplocale, _duplocale)
+
+locale_t
+duplocale(locale_t src)
+{
+       struct _locale *dst;
+
+       dst = malloc(sizeof(*dst));
+       if (dst != NULL)
+               memcpy(dst, src, sizeof(*dst));
+
+       return dst;
+}
Index: lib/libc/locale/freelocale.c
===================================================================
RCS file: lib/libc/locale/freelocale.c
diff -N lib/libc/locale/freelocale.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/libc/locale/freelocale.c        21 Apr 2013 18:32:46 -0000
@@ -0,0 +1,51 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c)2008, 2011 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD$");
+
+#include "namespace.h"
+
+#define __SETLOCALE_SOURCE__
+#include <assert.h>
+#include <locale.h>
+#include <stdlib.h>
+
+#include "setlocale_local.h"
+
+__weak_alias(freelocale, _freelocale)
+
+void
+freelocale(locale_t locale)
+{
+
+       _DIAGASSERT(locale != _LC_GLOBAL_LOCALE);
+       _DIAGASSERT(locale != NULL);
+       _DIAGASSERT(locale != &_global_locale);
+       free(locale);
+}
Index: lib/libc/locale/newlocale.c
===================================================================
RCS file: lib/libc/locale/newlocale.c
diff -N lib/libc/locale/newlocale.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/libc/locale/newlocale.c 22 Apr 2013 07:12:18 -0000
@@ -0,0 +1,101 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c)2008, 2011 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD$");
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "setlocale_local.h"
+
+__weak_alias(newlocale, _newlocale)
+
+locale_t
+newlocale(int mask, const char *name, locale_t src)
+{
+       struct _locale *dst;
+       char head[_LOCALENAME_LEN_MAX * (_LC_LAST - 1)], *tail;
+       const char *tokens[_LC_LAST - 1];
+       _locale_set_t l;
+       int i, howmany, categories[_LC_LAST - 1];
+
+       if (name == NULL)
+               name = _C_LOCALE;
+       dst = malloc(sizeof(*dst));
+       if (dst == NULL)
+               return (locale_t)NULL;
+       if (src == NULL)
+               src = *_current_locale();
+       memcpy(dst, src, sizeof(*src));
+       strlcpy(&head[0], name, sizeof(head));
+       tokens[0] = (const char *)&head[0];
+       tail = strchr(tokens[0], '/');
+       if (tail == NULL) {
+               for (i = 1; i < _LC_LAST; ++i) {
+                       if (mask & (1 << i)) {
+                               l = _find_category(i);
+                               _DIAGASSERT(l != NULL);
+                               (*l)(tokens[0], dst);
+                       }
+               }
+       } else {
+               *tail++ = '\0';
+               howmany = 0;
+               for (i = 1; i < _LC_LAST; ++i) {
+                       if (mask & (1 << i))
+                               categories[howmany++] = i;
+               }
+               if (howmany-- > 0) {
+                       for (i = 1; i < howmany; ++i) {
+                               tokens[i] = (const char *)tail;
+                               tail = strchr(tokens[i], '/');
+                               if (tail == NULL) {
+                                       free(dst);
+                                       return NULL;
+                               }
+                       }
+                       tokens[howmany] = tail;
+                       tail = strchr(tokens[howmany], '/');
+                       if (tail != NULL) {
+                               free(dst);
+                               return NULL;
+                       }
+                       for (i = 0; i <= howmany; ++i) {
+                               l = _find_category(categories[i]);
+                               _DIAGASSERT(l != NULL);
+                               (*l)(tokens[i], dst);
+                       }
+               }
+       }
+       return (locale_t)dst;
+}


Home | Main Index | Thread Index | Old Index