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.
This commit is contained in:
parent
f4cd4d5951
commit
81d0329e8d
@ -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 *) __RENAME(__setlocale50);
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
52
lib/libc/locale/duplocale.c
Normal file
52
lib/libc/locale/duplocale.c
Normal file
@ -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;
|
||||
}
|
51
lib/libc/locale/freelocale.c
Normal file
51
lib/libc/locale/freelocale.c
Normal file
@ -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);
|
||||
}
|
101
lib/libc/locale/newlocale.c
Normal file
101
lib/libc/locale/newlocale.c
Normal file
@ -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;
|
||||
}
|
@ -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_LAST] = {
|
||||
_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 *name)
|
||||
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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user