Module Name:    src
Committed By:   joerg
Date:           Tue Apr 30 00:45:05 UTC 2013

Modified Files:
        src/include: locale.h
        src/lib/libc/include: namespace.h
        src/lib/libc/locale: Makefile.inc setlocale.c
Added Files:
        src/lib/libc/locale: duplocale.c freelocale.c newlocale.c

Log Message:
Make that to process PATH_LOCALE the first time _find_category is
called. Use this to implement newlocale and provide duplocale/freelocale
as well. Based on patches by Takehiko Nozaki with simplications and fix
for the init order by myself.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/include/locale.h
cvs rdiff -u -r1.165 -r1.166 src/lib/libc/include/namespace.h
cvs rdiff -u -r1.61 -r1.62 src/lib/libc/locale/Makefile.inc \
    src/lib/libc/locale/setlocale.c
cvs rdiff -u -r0 -r1.1 src/lib/libc/locale/duplocale.c \
    src/lib/libc/locale/freelocale.c src/lib/libc/locale/newlocale.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/include/locale.h
diff -u src/include/locale.h:1.20 src/include/locale.h:1.21
--- src/include/locale.h:1.20	Sat Apr 27 21:24:27 2013
+++ src/include/locale.h	Tue Apr 30 00:45:04 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: locale.h,v 1.20 2013/04/27 21:24:27 joerg Exp $	*/
+/*	$NetBSD: locale.h,v 1.21 2013/04/30 00:45:04 joerg Exp $	*/
 
 /*
  * Copyright (c) 1991, 1993
@@ -98,7 +98,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))
+locale_t	duplocale(locale_t);
+void		freelocale(locale_t);
 struct lconv	*localeconv_l(locale_t);
+locale_t	newlocale(int, const char *, locale_t);
 #endif
 __END_DECLS
 

Index: src/lib/libc/include/namespace.h
diff -u src/lib/libc/include/namespace.h:1.165 src/lib/libc/include/namespace.h:1.166
--- src/lib/libc/include/namespace.h:1.165	Sun Apr 21 17:45:46 2013
+++ src/lib/libc/include/namespace.h	Tue Apr 30 00:45:04 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: namespace.h,v 1.165 2013/04/21 17:45:46 joerg Exp $	*/
+/*	$NetBSD: namespace.h,v 1.166 2013/04/30 00:45:04 joerg Exp $	*/
 
 /*-
  * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@@ -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: src/lib/libc/locale/Makefile.inc
diff -u src/lib/libc/locale/Makefile.inc:1.61 src/lib/libc/locale/Makefile.inc:1.62
--- src/lib/libc/locale/Makefile.inc:1.61	Sun Apr 14 23:44:53 2013
+++ src/lib/libc/locale/Makefile.inc	Tue Apr 30 00:45:05 2013
@@ -1,13 +1,13 @@
 #	from: @(#)Makefile.inc	5.1 (Berkeley) 2/18/91
-#	$NetBSD: Makefile.inc,v 1.61 2013/04/14 23:44:53 joerg Exp $
+#	$NetBSD: Makefile.inc,v 1.62 2013/04/30 00:45:05 joerg Exp $
 
 # locale sources
 .PATH: ${ARCHDIR}/locale ${.CURDIR}/locale
 
 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: src/lib/libc/locale/setlocale.c
diff -u src/lib/libc/locale/setlocale.c:1.61 src/lib/libc/locale/setlocale.c:1.62
--- src/lib/libc/locale/setlocale.c:1.61	Sun Apr 14 23:30:16 2013
+++ src/lib/libc/locale/setlocale.c	Tue Apr 30 00:45:05 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: setlocale.c,v 1.61 2013/04/14 23:30:16 joerg Exp $ */
+/* $NetBSD: setlocale.c,v 1.62 2013/04/30 00:45:05 joerg Exp $ */
 
 /*-
  * Copyright (c)2008 Citrus Project,
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: setlocale.c,v 1.61 2013/04/14 23:30:16 joerg Exp $");
+__RCSID("$NetBSD: setlocale.c,v 1.62 2013/04/30 00:45:05 joerg Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
@@ -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));
 }

Added files:

Index: src/lib/libc/locale/duplocale.c
diff -u /dev/null src/lib/libc/locale/duplocale.c:1.1
--- /dev/null	Tue Apr 30 00:45:05 2013
+++ src/lib/libc/locale/duplocale.c	Tue Apr 30 00:45:05 2013
@@ -0,0 +1,52 @@
+/* $NetBSD: duplocale.c,v 1.1 2013/04/30 00:45:05 joerg Exp $ */
+
+/*-
+ * 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: duplocale.c,v 1.1 2013/04/30 00:45:05 joerg Exp $");
+
+#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: src/lib/libc/locale/freelocale.c
diff -u /dev/null src/lib/libc/locale/freelocale.c:1.1
--- /dev/null	Tue Apr 30 00:45:06 2013
+++ src/lib/libc/locale/freelocale.c	Tue Apr 30 00:45:05 2013
@@ -0,0 +1,51 @@
+/* $NetBSD: freelocale.c,v 1.1 2013/04/30 00:45:05 joerg Exp $ */
+
+/*-
+ * 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: freelocale.c,v 1.1 2013/04/30 00:45:05 joerg Exp $");
+
+#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: src/lib/libc/locale/newlocale.c
diff -u /dev/null src/lib/libc/locale/newlocale.c:1.1
--- /dev/null	Tue Apr 30 00:45:06 2013
+++ src/lib/libc/locale/newlocale.c	Tue Apr 30 00:45:05 2013
@@ -0,0 +1,101 @@
+/* $NetBSD: newlocale.c,v 1.1 2013/04/30 00:45:05 joerg Exp $ */
+
+/*-
+ * 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: newlocale.c,v 1.1 2013/04/30 00:45:05 joerg Exp $");
+
+#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;
+}

Reply via email to