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